diff options
Diffstat (limited to 'drivers/media/platform/coda.c')
-rw-r--r-- | drivers/media/platform/coda.c | 278 |
1 files changed, 172 insertions, 106 deletions
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 4993610051ee..bd72fb97fea5 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | #define CODA_NAME "coda" | 40 | #define CODA_NAME "coda" |
41 | 41 | ||
42 | #define CODA_MAX_INSTANCES 4 | 42 | #define CODADX6_MAX_INSTANCES 4 |
43 | 43 | ||
44 | #define CODA_FMO_BUF_SIZE 32 | 44 | #define CODA_FMO_BUF_SIZE 32 |
45 | #define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024) | 45 | #define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024) |
@@ -54,8 +54,6 @@ | |||
54 | 54 | ||
55 | #define CODA_MAX_FRAMEBUFFERS 8 | 55 | #define CODA_MAX_FRAMEBUFFERS 8 |
56 | 56 | ||
57 | #define MAX_W 8192 | ||
58 | #define MAX_H 8192 | ||
59 | #define CODA_MAX_FRAME_SIZE 0x100000 | 57 | #define CODA_MAX_FRAME_SIZE 0x100000 |
60 | #define FMO_SLICE_SAVE_BUF_SIZE (32) | 58 | #define FMO_SLICE_SAVE_BUF_SIZE (32) |
61 | #define CODA_DEFAULT_GAMMA 4096 | 59 | #define CODA_DEFAULT_GAMMA 4096 |
@@ -394,14 +392,57 @@ static struct coda_codec *coda_find_codec(struct coda_dev *dev, int src_fourcc, | |||
394 | return &codecs[k]; | 392 | return &codecs[k]; |
395 | } | 393 | } |
396 | 394 | ||
395 | static void coda_get_max_dimensions(struct coda_dev *dev, | ||
396 | struct coda_codec *codec, | ||
397 | int *max_w, int *max_h) | ||
398 | { | ||
399 | struct coda_codec *codecs = dev->devtype->codecs; | ||
400 | int num_codecs = dev->devtype->num_codecs; | ||
401 | unsigned int w, h; | ||
402 | int k; | ||
403 | |||
404 | if (codec) { | ||
405 | w = codec->max_w; | ||
406 | h = codec->max_h; | ||
407 | } else { | ||
408 | for (k = 0, w = 0, h = 0; k < num_codecs; k++) { | ||
409 | w = max(w, codecs[k].max_w); | ||
410 | h = max(h, codecs[k].max_h); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | if (max_w) | ||
415 | *max_w = w; | ||
416 | if (max_h) | ||
417 | *max_h = h; | ||
418 | } | ||
419 | |||
420 | static char *coda_product_name(int product) | ||
421 | { | ||
422 | static char buf[9]; | ||
423 | |||
424 | switch (product) { | ||
425 | case CODA_DX6: | ||
426 | return "CodaDx6"; | ||
427 | case CODA_7541: | ||
428 | return "CODA7541"; | ||
429 | default: | ||
430 | snprintf(buf, sizeof(buf), "(0x%04x)", product); | ||
431 | return buf; | ||
432 | } | ||
433 | } | ||
434 | |||
397 | /* | 435 | /* |
398 | * V4L2 ioctl() operations. | 436 | * V4L2 ioctl() operations. |
399 | */ | 437 | */ |
400 | static int vidioc_querycap(struct file *file, void *priv, | 438 | static int coda_querycap(struct file *file, void *priv, |
401 | struct v4l2_capability *cap) | 439 | struct v4l2_capability *cap) |
402 | { | 440 | { |
441 | struct coda_ctx *ctx = fh_to_ctx(priv); | ||
442 | |||
403 | strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver)); | 443 | strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver)); |
404 | strlcpy(cap->card, CODA_NAME, sizeof(cap->card)); | 444 | strlcpy(cap->card, coda_product_name(ctx->dev->devtype->product), |
445 | sizeof(cap->card)); | ||
405 | strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); | 446 | strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); |
406 | /* | 447 | /* |
407 | * This is only a mem-to-mem video device. The capture and output | 448 | * This is only a mem-to-mem video device. The capture and output |
@@ -457,6 +498,8 @@ static int enum_fmt(void *priv, struct v4l2_fmtdesc *f, | |||
457 | fmt = &formats[i]; | 498 | fmt = &formats[i]; |
458 | strlcpy(f->description, fmt->name, sizeof(f->description)); | 499 | strlcpy(f->description, fmt->name, sizeof(f->description)); |
459 | f->pixelformat = fmt->fourcc; | 500 | f->pixelformat = fmt->fourcc; |
501 | if (!coda_format_is_yuv(fmt->fourcc)) | ||
502 | f->flags |= V4L2_FMT_FLAG_COMPRESSED; | ||
460 | return 0; | 503 | return 0; |
461 | } | 504 | } |
462 | 505 | ||
@@ -464,8 +507,8 @@ static int enum_fmt(void *priv, struct v4l2_fmtdesc *f, | |||
464 | return -EINVAL; | 507 | return -EINVAL; |
465 | } | 508 | } |
466 | 509 | ||
467 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | 510 | static int coda_enum_fmt_vid_cap(struct file *file, void *priv, |
468 | struct v4l2_fmtdesc *f) | 511 | struct v4l2_fmtdesc *f) |
469 | { | 512 | { |
470 | struct coda_ctx *ctx = fh_to_ctx(priv); | 513 | struct coda_ctx *ctx = fh_to_ctx(priv); |
471 | struct vb2_queue *src_vq; | 514 | struct vb2_queue *src_vq; |
@@ -483,13 +526,14 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | |||
483 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0); | 526 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0); |
484 | } | 527 | } |
485 | 528 | ||
486 | static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, | 529 | static int coda_enum_fmt_vid_out(struct file *file, void *priv, |
487 | struct v4l2_fmtdesc *f) | 530 | struct v4l2_fmtdesc *f) |
488 | { | 531 | { |
489 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0); | 532 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0); |
490 | } | 533 | } |
491 | 534 | ||
492 | static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | 535 | static int coda_g_fmt(struct file *file, void *priv, |
536 | struct v4l2_format *f) | ||
493 | { | 537 | { |
494 | struct vb2_queue *vq; | 538 | struct vb2_queue *vq; |
495 | struct coda_q_data *q_data; | 539 | struct coda_q_data *q_data; |
@@ -516,8 +560,11 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
516 | return 0; | 560 | return 0; |
517 | } | 561 | } |
518 | 562 | ||
519 | static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f) | 563 | static int coda_try_fmt(struct coda_ctx *ctx, struct coda_codec *codec, |
564 | struct v4l2_format *f) | ||
520 | { | 565 | { |
566 | struct coda_dev *dev = ctx->dev; | ||
567 | struct coda_q_data *q_data; | ||
521 | unsigned int max_w, max_h; | 568 | unsigned int max_w, max_h; |
522 | enum v4l2_field field; | 569 | enum v4l2_field field; |
523 | 570 | ||
@@ -531,32 +578,48 @@ static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f) | |||
531 | * if any of the dimensions is unsupported */ | 578 | * if any of the dimensions is unsupported */ |
532 | f->fmt.pix.field = field; | 579 | f->fmt.pix.field = field; |
533 | 580 | ||
534 | if (codec) { | 581 | coda_get_max_dimensions(dev, codec, &max_w, &max_h); |
535 | max_w = codec->max_w; | 582 | v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, W_ALIGN, |
536 | max_h = codec->max_h; | 583 | &f->fmt.pix.height, MIN_H, max_h, H_ALIGN, |
537 | } else { | 584 | S_ALIGN); |
538 | max_w = MAX_W; | 585 | |
539 | max_h = MAX_H; | 586 | switch (f->fmt.pix.pixelformat) { |
587 | case V4L2_PIX_FMT_YUV420: | ||
588 | case V4L2_PIX_FMT_YVU420: | ||
589 | case V4L2_PIX_FMT_H264: | ||
590 | case V4L2_PIX_FMT_MPEG4: | ||
591 | case V4L2_PIX_FMT_JPEG: | ||
592 | break; | ||
593 | default: | ||
594 | q_data = get_q_data(ctx, f->type); | ||
595 | f->fmt.pix.pixelformat = q_data->fourcc; | ||
540 | } | 596 | } |
541 | v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, | ||
542 | W_ALIGN, &f->fmt.pix.height, | ||
543 | MIN_H, max_h, H_ALIGN, S_ALIGN); | ||
544 | 597 | ||
545 | if (coda_format_is_yuv(f->fmt.pix.pixelformat)) { | 598 | switch (f->fmt.pix.pixelformat) { |
599 | case V4L2_PIX_FMT_YUV420: | ||
600 | case V4L2_PIX_FMT_YVU420: | ||
546 | /* Frame stride must be multiple of 8 */ | 601 | /* Frame stride must be multiple of 8 */ |
547 | f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8); | 602 | f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8); |
548 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * | 603 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * |
549 | f->fmt.pix.height * 3 / 2; | 604 | f->fmt.pix.height * 3 / 2; |
550 | } else { /*encoded formats h.264/mpeg4 */ | 605 | break; |
606 | case V4L2_PIX_FMT_H264: | ||
607 | case V4L2_PIX_FMT_MPEG4: | ||
608 | case V4L2_PIX_FMT_JPEG: | ||
551 | f->fmt.pix.bytesperline = 0; | 609 | f->fmt.pix.bytesperline = 0; |
552 | f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE; | 610 | f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE; |
611 | break; | ||
612 | default: | ||
613 | BUG(); | ||
553 | } | 614 | } |
554 | 615 | ||
616 | f->fmt.pix.priv = 0; | ||
617 | |||
555 | return 0; | 618 | return 0; |
556 | } | 619 | } |
557 | 620 | ||
558 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | 621 | static int coda_try_fmt_vid_cap(struct file *file, void *priv, |
559 | struct v4l2_format *f) | 622 | struct v4l2_format *f) |
560 | { | 623 | { |
561 | struct coda_ctx *ctx = fh_to_ctx(priv); | 624 | struct coda_ctx *ctx = fh_to_ctx(priv); |
562 | struct coda_codec *codec; | 625 | struct coda_codec *codec; |
@@ -584,7 +647,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
584 | 647 | ||
585 | f->fmt.pix.colorspace = ctx->colorspace; | 648 | f->fmt.pix.colorspace = ctx->colorspace; |
586 | 649 | ||
587 | ret = vidioc_try_fmt(codec, f); | 650 | ret = coda_try_fmt(ctx, codec, f); |
588 | if (ret < 0) | 651 | if (ret < 0) |
589 | return ret; | 652 | return ret; |
590 | 653 | ||
@@ -600,8 +663,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
600 | return 0; | 663 | return 0; |
601 | } | 664 | } |
602 | 665 | ||
603 | static int vidioc_try_fmt_vid_out(struct file *file, void *priv, | 666 | static int coda_try_fmt_vid_out(struct file *file, void *priv, |
604 | struct v4l2_format *f) | 667 | struct v4l2_format *f) |
605 | { | 668 | { |
606 | struct coda_ctx *ctx = fh_to_ctx(priv); | 669 | struct coda_ctx *ctx = fh_to_ctx(priv); |
607 | struct coda_codec *codec; | 670 | struct coda_codec *codec; |
@@ -613,10 +676,10 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv, | |||
613 | if (!f->fmt.pix.colorspace) | 676 | if (!f->fmt.pix.colorspace) |
614 | f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; | 677 | f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; |
615 | 678 | ||
616 | return vidioc_try_fmt(codec, f); | 679 | return coda_try_fmt(ctx, codec, f); |
617 | } | 680 | } |
618 | 681 | ||
619 | static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f) | 682 | static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f) |
620 | { | 683 | { |
621 | struct coda_q_data *q_data; | 684 | struct coda_q_data *q_data; |
622 | struct vb2_queue *vq; | 685 | struct vb2_queue *vq; |
@@ -646,61 +709,62 @@ static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f) | |||
646 | return 0; | 709 | return 0; |
647 | } | 710 | } |
648 | 711 | ||
649 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | 712 | static int coda_s_fmt_vid_cap(struct file *file, void *priv, |
650 | struct v4l2_format *f) | 713 | struct v4l2_format *f) |
651 | { | 714 | { |
652 | struct coda_ctx *ctx = fh_to_ctx(priv); | 715 | struct coda_ctx *ctx = fh_to_ctx(priv); |
653 | int ret; | 716 | int ret; |
654 | 717 | ||
655 | ret = vidioc_try_fmt_vid_cap(file, priv, f); | 718 | ret = coda_try_fmt_vid_cap(file, priv, f); |
656 | if (ret) | 719 | if (ret) |
657 | return ret; | 720 | return ret; |
658 | 721 | ||
659 | return vidioc_s_fmt(ctx, f); | 722 | return coda_s_fmt(ctx, f); |
660 | } | 723 | } |
661 | 724 | ||
662 | static int vidioc_s_fmt_vid_out(struct file *file, void *priv, | 725 | static int coda_s_fmt_vid_out(struct file *file, void *priv, |
663 | struct v4l2_format *f) | 726 | struct v4l2_format *f) |
664 | { | 727 | { |
665 | struct coda_ctx *ctx = fh_to_ctx(priv); | 728 | struct coda_ctx *ctx = fh_to_ctx(priv); |
666 | int ret; | 729 | int ret; |
667 | 730 | ||
668 | ret = vidioc_try_fmt_vid_out(file, priv, f); | 731 | ret = coda_try_fmt_vid_out(file, priv, f); |
669 | if (ret) | 732 | if (ret) |
670 | return ret; | 733 | return ret; |
671 | 734 | ||
672 | ret = vidioc_s_fmt(ctx, f); | 735 | ret = coda_s_fmt(ctx, f); |
673 | if (ret) | 736 | if (ret) |
674 | ctx->colorspace = f->fmt.pix.colorspace; | 737 | ctx->colorspace = f->fmt.pix.colorspace; |
675 | 738 | ||
676 | return ret; | 739 | return ret; |
677 | } | 740 | } |
678 | 741 | ||
679 | static int vidioc_reqbufs(struct file *file, void *priv, | 742 | static int coda_reqbufs(struct file *file, void *priv, |
680 | struct v4l2_requestbuffers *reqbufs) | 743 | struct v4l2_requestbuffers *reqbufs) |
681 | { | 744 | { |
682 | struct coda_ctx *ctx = fh_to_ctx(priv); | 745 | struct coda_ctx *ctx = fh_to_ctx(priv); |
683 | 746 | ||
684 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); | 747 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); |
685 | } | 748 | } |
686 | 749 | ||
687 | static int vidioc_querybuf(struct file *file, void *priv, | 750 | static int coda_querybuf(struct file *file, void *priv, |
688 | struct v4l2_buffer *buf) | 751 | struct v4l2_buffer *buf) |
689 | { | 752 | { |
690 | struct coda_ctx *ctx = fh_to_ctx(priv); | 753 | struct coda_ctx *ctx = fh_to_ctx(priv); |
691 | 754 | ||
692 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); | 755 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); |
693 | } | 756 | } |
694 | 757 | ||
695 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | 758 | static int coda_qbuf(struct file *file, void *priv, |
759 | struct v4l2_buffer *buf) | ||
696 | { | 760 | { |
697 | struct coda_ctx *ctx = fh_to_ctx(priv); | 761 | struct coda_ctx *ctx = fh_to_ctx(priv); |
698 | 762 | ||
699 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); | 763 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); |
700 | } | 764 | } |
701 | 765 | ||
702 | static int vidioc_expbuf(struct file *file, void *priv, | 766 | static int coda_expbuf(struct file *file, void *priv, |
703 | struct v4l2_exportbuffer *eb) | 767 | struct v4l2_exportbuffer *eb) |
704 | { | 768 | { |
705 | struct coda_ctx *ctx = fh_to_ctx(priv); | 769 | struct coda_ctx *ctx = fh_to_ctx(priv); |
706 | 770 | ||
@@ -718,7 +782,8 @@ static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx, | |||
718 | (buf->sequence == (ctx->qsequence - 1))); | 782 | (buf->sequence == (ctx->qsequence - 1))); |
719 | } | 783 | } |
720 | 784 | ||
721 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | 785 | static int coda_dqbuf(struct file *file, void *priv, |
786 | struct v4l2_buffer *buf) | ||
722 | { | 787 | { |
723 | struct coda_ctx *ctx = fh_to_ctx(priv); | 788 | struct coda_ctx *ctx = fh_to_ctx(priv); |
724 | int ret; | 789 | int ret; |
@@ -738,24 +803,24 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | |||
738 | return ret; | 803 | return ret; |
739 | } | 804 | } |
740 | 805 | ||
741 | static int vidioc_create_bufs(struct file *file, void *priv, | 806 | static int coda_create_bufs(struct file *file, void *priv, |
742 | struct v4l2_create_buffers *create) | 807 | struct v4l2_create_buffers *create) |
743 | { | 808 | { |
744 | struct coda_ctx *ctx = fh_to_ctx(priv); | 809 | struct coda_ctx *ctx = fh_to_ctx(priv); |
745 | 810 | ||
746 | return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create); | 811 | return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create); |
747 | } | 812 | } |
748 | 813 | ||
749 | static int vidioc_streamon(struct file *file, void *priv, | 814 | static int coda_streamon(struct file *file, void *priv, |
750 | enum v4l2_buf_type type) | 815 | enum v4l2_buf_type type) |
751 | { | 816 | { |
752 | struct coda_ctx *ctx = fh_to_ctx(priv); | 817 | struct coda_ctx *ctx = fh_to_ctx(priv); |
753 | 818 | ||
754 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); | 819 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); |
755 | } | 820 | } |
756 | 821 | ||
757 | static int vidioc_streamoff(struct file *file, void *priv, | 822 | static int coda_streamoff(struct file *file, void *priv, |
758 | enum v4l2_buf_type type) | 823 | enum v4l2_buf_type type) |
759 | { | 824 | { |
760 | struct coda_ctx *ctx = fh_to_ctx(priv); | 825 | struct coda_ctx *ctx = fh_to_ctx(priv); |
761 | int ret; | 826 | int ret; |
@@ -772,23 +837,34 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
772 | return ret; | 837 | return ret; |
773 | } | 838 | } |
774 | 839 | ||
775 | static int vidioc_decoder_cmd(struct file *file, void *fh, | 840 | static int coda_try_decoder_cmd(struct file *file, void *fh, |
776 | struct v4l2_decoder_cmd *dc) | 841 | struct v4l2_decoder_cmd *dc) |
777 | { | 842 | { |
778 | struct coda_ctx *ctx = fh_to_ctx(fh); | ||
779 | |||
780 | if (dc->cmd != V4L2_DEC_CMD_STOP) | 843 | if (dc->cmd != V4L2_DEC_CMD_STOP) |
781 | return -EINVAL; | 844 | return -EINVAL; |
782 | 845 | ||
783 | if ((dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK) || | 846 | if (dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK) |
784 | (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)) | ||
785 | return -EINVAL; | 847 | return -EINVAL; |
786 | 848 | ||
787 | if (dc->stop.pts != 0) | 849 | if (!(dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) && (dc->stop.pts != 0)) |
788 | return -EINVAL; | 850 | return -EINVAL; |
789 | 851 | ||
852 | return 0; | ||
853 | } | ||
854 | |||
855 | static int coda_decoder_cmd(struct file *file, void *fh, | ||
856 | struct v4l2_decoder_cmd *dc) | ||
857 | { | ||
858 | struct coda_ctx *ctx = fh_to_ctx(fh); | ||
859 | int ret; | ||
860 | |||
861 | ret = coda_try_decoder_cmd(file, fh, dc); | ||
862 | if (ret < 0) | ||
863 | return ret; | ||
864 | |||
865 | /* Ignore decoder stop command silently in encoder context */ | ||
790 | if (ctx->inst_type != CODA_INST_DECODER) | 866 | if (ctx->inst_type != CODA_INST_DECODER) |
791 | return -EINVAL; | 867 | return 0; |
792 | 868 | ||
793 | /* Set the strem-end flag on this context */ | 869 | /* Set the strem-end flag on this context */ |
794 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; | 870 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; |
@@ -796,8 +872,8 @@ static int vidioc_decoder_cmd(struct file *file, void *fh, | |||
796 | return 0; | 872 | return 0; |
797 | } | 873 | } |
798 | 874 | ||
799 | static int vidioc_subscribe_event(struct v4l2_fh *fh, | 875 | static int coda_subscribe_event(struct v4l2_fh *fh, |
800 | const struct v4l2_event_subscription *sub) | 876 | const struct v4l2_event_subscription *sub) |
801 | { | 877 | { |
802 | switch (sub->type) { | 878 | switch (sub->type) { |
803 | case V4L2_EVENT_EOS: | 879 | case V4L2_EVENT_EOS: |
@@ -808,32 +884,33 @@ static int vidioc_subscribe_event(struct v4l2_fh *fh, | |||
808 | } | 884 | } |
809 | 885 | ||
810 | static const struct v4l2_ioctl_ops coda_ioctl_ops = { | 886 | static const struct v4l2_ioctl_ops coda_ioctl_ops = { |
811 | .vidioc_querycap = vidioc_querycap, | 887 | .vidioc_querycap = coda_querycap, |
812 | 888 | ||
813 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | 889 | .vidioc_enum_fmt_vid_cap = coda_enum_fmt_vid_cap, |
814 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt, | 890 | .vidioc_g_fmt_vid_cap = coda_g_fmt, |
815 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | 891 | .vidioc_try_fmt_vid_cap = coda_try_fmt_vid_cap, |
816 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | 892 | .vidioc_s_fmt_vid_cap = coda_s_fmt_vid_cap, |
817 | 893 | ||
818 | .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, | 894 | .vidioc_enum_fmt_vid_out = coda_enum_fmt_vid_out, |
819 | .vidioc_g_fmt_vid_out = vidioc_g_fmt, | 895 | .vidioc_g_fmt_vid_out = coda_g_fmt, |
820 | .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, | 896 | .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out, |
821 | .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, | 897 | .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out, |
822 | 898 | ||
823 | .vidioc_reqbufs = vidioc_reqbufs, | 899 | .vidioc_reqbufs = coda_reqbufs, |
824 | .vidioc_querybuf = vidioc_querybuf, | 900 | .vidioc_querybuf = coda_querybuf, |
825 | 901 | ||
826 | .vidioc_qbuf = vidioc_qbuf, | 902 | .vidioc_qbuf = coda_qbuf, |
827 | .vidioc_expbuf = vidioc_expbuf, | 903 | .vidioc_expbuf = coda_expbuf, |
828 | .vidioc_dqbuf = vidioc_dqbuf, | 904 | .vidioc_dqbuf = coda_dqbuf, |
829 | .vidioc_create_bufs = vidioc_create_bufs, | 905 | .vidioc_create_bufs = coda_create_bufs, |
830 | 906 | ||
831 | .vidioc_streamon = vidioc_streamon, | 907 | .vidioc_streamon = coda_streamon, |
832 | .vidioc_streamoff = vidioc_streamoff, | 908 | .vidioc_streamoff = coda_streamoff, |
833 | 909 | ||
834 | .vidioc_decoder_cmd = vidioc_decoder_cmd, | 910 | .vidioc_try_decoder_cmd = coda_try_decoder_cmd, |
911 | .vidioc_decoder_cmd = coda_decoder_cmd, | ||
835 | 912 | ||
836 | .vidioc_subscribe_event = vidioc_subscribe_event, | 913 | .vidioc_subscribe_event = coda_subscribe_event, |
837 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | 914 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
838 | }; | 915 | }; |
839 | 916 | ||
@@ -1928,8 +2005,9 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) | |||
1928 | if (!(ctx->streamon_out & ctx->streamon_cap)) | 2005 | if (!(ctx->streamon_out & ctx->streamon_cap)) |
1929 | return 0; | 2006 | return 0; |
1930 | 2007 | ||
1931 | /* Allow device_run with no buffers queued and after streamoff */ | 2008 | /* Allow decoder device_run with no new buffers queued */ |
1932 | v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true); | 2009 | if (ctx->inst_type == CODA_INST_DECODER) |
2010 | v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true); | ||
1933 | 2011 | ||
1934 | ctx->gopcounter = ctx->params.gop_size - 1; | 2012 | ctx->gopcounter = ctx->params.gop_size - 1; |
1935 | buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); | 2013 | buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); |
@@ -2071,10 +2149,8 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) | |||
2071 | coda_setup_iram(ctx); | 2149 | coda_setup_iram(ctx); |
2072 | 2150 | ||
2073 | if (dst_fourcc == V4L2_PIX_FMT_H264) { | 2151 | if (dst_fourcc == V4L2_PIX_FMT_H264) { |
2074 | value = (FMO_SLICE_SAVE_BUF_SIZE << 7); | ||
2075 | value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET; | ||
2076 | value |= 0 & CODA_FMOPARAM_SLICENUM_MASK; | ||
2077 | if (dev->devtype->product == CODA_DX6) { | 2152 | if (dev->devtype->product == CODA_DX6) { |
2153 | value = FMO_SLICE_SAVE_BUF_SIZE << 7; | ||
2078 | coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO); | 2154 | coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO); |
2079 | } else { | 2155 | } else { |
2080 | coda_write(dev, ctx->iram_info.search_ram_paddr, | 2156 | coda_write(dev, ctx->iram_info.search_ram_paddr, |
@@ -2371,7 +2447,13 @@ static int coda_queue_init(void *priv, struct vb2_queue *src_vq, | |||
2371 | 2447 | ||
2372 | static int coda_next_free_instance(struct coda_dev *dev) | 2448 | static int coda_next_free_instance(struct coda_dev *dev) |
2373 | { | 2449 | { |
2374 | return ffz(dev->instance_mask); | 2450 | int idx = ffz(dev->instance_mask); |
2451 | |||
2452 | if ((idx < 0) || | ||
2453 | (dev->devtype->product == CODA_DX6 && idx > CODADX6_MAX_INSTANCES)) | ||
2454 | return -EBUSY; | ||
2455 | |||
2456 | return idx; | ||
2375 | } | 2457 | } |
2376 | 2458 | ||
2377 | static int coda_open(struct file *file) | 2459 | static int coda_open(struct file *file) |
@@ -2386,8 +2468,8 @@ static int coda_open(struct file *file) | |||
2386 | return -ENOMEM; | 2468 | return -ENOMEM; |
2387 | 2469 | ||
2388 | idx = coda_next_free_instance(dev); | 2470 | idx = coda_next_free_instance(dev); |
2389 | if (idx >= CODA_MAX_INSTANCES) { | 2471 | if (idx < 0) { |
2390 | ret = -EBUSY; | 2472 | ret = idx; |
2391 | goto err_coda_max; | 2473 | goto err_coda_max; |
2392 | } | 2474 | } |
2393 | set_bit(idx, &dev->instance_mask); | 2475 | set_bit(idx, &dev->instance_mask); |
@@ -2719,7 +2801,6 @@ static void coda_finish_encode(struct coda_ctx *ctx) | |||
2719 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); | 2801 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); |
2720 | 2802 | ||
2721 | /* Get results from the coda */ | 2803 | /* Get results from the coda */ |
2722 | coda_read(dev, CODA_RET_ENC_PIC_TYPE); | ||
2723 | start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START); | 2804 | start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START); |
2724 | wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); | 2805 | wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); |
2725 | 2806 | ||
@@ -2739,7 +2820,7 @@ static void coda_finish_encode(struct coda_ctx *ctx) | |||
2739 | coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM); | 2820 | coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM); |
2740 | coda_read(dev, CODA_RET_ENC_PIC_FLAG); | 2821 | coda_read(dev, CODA_RET_ENC_PIC_FLAG); |
2741 | 2822 | ||
2742 | if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) { | 2823 | if (coda_read(dev, CODA_RET_ENC_PIC_TYPE) == 0) { |
2743 | dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; | 2824 | dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; |
2744 | dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME; | 2825 | dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME; |
2745 | } else { | 2826 | } else { |
@@ -2861,21 +2942,6 @@ static bool coda_firmware_supported(u32 vernum) | |||
2861 | return false; | 2942 | return false; |
2862 | } | 2943 | } |
2863 | 2944 | ||
2864 | static char *coda_product_name(int product) | ||
2865 | { | ||
2866 | static char buf[9]; | ||
2867 | |||
2868 | switch (product) { | ||
2869 | case CODA_DX6: | ||
2870 | return "CodaDx6"; | ||
2871 | case CODA_7541: | ||
2872 | return "CODA7541"; | ||
2873 | default: | ||
2874 | snprintf(buf, sizeof(buf), "(0x%04x)", product); | ||
2875 | return buf; | ||
2876 | } | ||
2877 | } | ||
2878 | |||
2879 | static int coda_hw_init(struct coda_dev *dev) | 2945 | static int coda_hw_init(struct coda_dev *dev) |
2880 | { | 2946 | { |
2881 | u16 product, major, minor, release; | 2947 | u16 product, major, minor, release; |