forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/media/platform/omap/omap_vout.c
....@@ -40,9 +40,9 @@
4040 #include <linux/dma-mapping.h>
4141 #include <linux/slab.h>
4242
43
-#include <media/videobuf-dma-contig.h>
4443 #include <media/v4l2-device.h>
4544 #include <media/v4l2-ioctl.h>
45
+#include <media/v4l2-event.h>
4646
4747 #include <video/omapvrfb.h>
4848 #include <video/omapfb_dss.h>
....@@ -63,33 +63,12 @@
6363 OMAP_VIDEO2,
6464 };
6565
66
-static struct videobuf_queue_ops video_vbq_ops;
6766 /* Variables configurable through module params*/
68
-static u32 video1_numbuffers = 3;
69
-static u32 video2_numbuffers = 3;
70
-static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
71
-static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
7267 static bool vid1_static_vrfb_alloc;
7368 static bool vid2_static_vrfb_alloc;
7469 static bool debug;
7570
7671 /* Module parameters */
77
-module_param(video1_numbuffers, uint, S_IRUGO);
78
-MODULE_PARM_DESC(video1_numbuffers,
79
- "Number of buffers to be allocated at init time for Video1 device.");
80
-
81
-module_param(video2_numbuffers, uint, S_IRUGO);
82
-MODULE_PARM_DESC(video2_numbuffers,
83
- "Number of buffers to be allocated at init time for Video2 device.");
84
-
85
-module_param(video1_bufsize, uint, S_IRUGO);
86
-MODULE_PARM_DESC(video1_bufsize,
87
- "Size of the buffer to be allocated for video1 device");
88
-
89
-module_param(video2_bufsize, uint, S_IRUGO);
90
-MODULE_PARM_DESC(video2_bufsize,
91
- "Size of the buffer to be allocated for video2 device");
92
-
9372 module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
9473 MODULE_PARM_DESC(vid1_static_vrfb_alloc,
9574 "Static allocation of the VRFB buffer for video1 device");
....@@ -114,14 +93,12 @@
11493 * Byte 0 Byte 1
11594 * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3
11695 */
117
- .description = "RGB565, le",
11896 .pixelformat = V4L2_PIX_FMT_RGB565,
11997 },
12098 {
12199 /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use
122100 * this for RGB24 unpack mode, the last 8 bits are ignored
123101 * */
124
- .description = "RGB32, le",
125102 .pixelformat = V4L2_PIX_FMT_RGB32,
126103 },
127104 {
....@@ -129,15 +106,12 @@
129106 * this for RGB24 packed mode
130107 *
131108 */
132
- .description = "RGB24, le",
133109 .pixelformat = V4L2_PIX_FMT_RGB24,
134110 },
135111 {
136
- .description = "YUYV (YUV 4:2:2), packed",
137112 .pixelformat = V4L2_PIX_FMT_YUYV,
138113 },
139114 {
140
- .description = "UYVY, packed",
141115 .pixelformat = V4L2_PIX_FMT_UYVY,
142116 },
143117 };
....@@ -164,13 +138,13 @@
164138 ifmt = 0;
165139
166140 pix->pixelformat = omap_formats[ifmt].pixelformat;
167
- pix->field = V4L2_FIELD_ANY;
141
+ pix->field = V4L2_FIELD_NONE;
168142
169143 switch (pix->pixelformat) {
170144 case V4L2_PIX_FMT_YUYV:
171145 case V4L2_PIX_FMT_UYVY:
172146 default:
173
- pix->colorspace = V4L2_COLORSPACE_JPEG;
147
+ pix->colorspace = V4L2_COLORSPACE_SRGB;
174148 bpp = YUYV_BPP;
175149 break;
176150 case V4L2_PIX_FMT_RGB565:
....@@ -192,56 +166,6 @@
192166 pix->sizeimage = pix->bytesperline * pix->height;
193167
194168 return bpp;
195
-}
196
-
197
-/*
198
- * omap_vout_get_userptr: Convert user space virtual address to physical
199
- * address.
200
- */
201
-static int omap_vout_get_userptr(struct videobuf_buffer *vb, long virtp,
202
- u32 *physp)
203
-{
204
- struct frame_vector *vec;
205
- int ret;
206
-
207
- /* For kernel direct-mapped memory, take the easy way */
208
- if (virtp >= PAGE_OFFSET) {
209
- *physp = virt_to_phys((void *)virtp);
210
- return 0;
211
- }
212
-
213
- vec = frame_vector_create(1);
214
- if (!vec)
215
- return -ENOMEM;
216
-
217
- ret = get_vaddr_frames(virtp, 1, FOLL_WRITE, vec);
218
- if (ret != 1) {
219
- frame_vector_destroy(vec);
220
- return -EINVAL;
221
- }
222
- *physp = __pfn_to_phys(frame_vector_pfns(vec)[0]);
223
- vb->priv = vec;
224
-
225
- return 0;
226
-}
227
-
228
-/*
229
- * Free the V4L2 buffers
230
- */
231
-void omap_vout_free_buffers(struct omap_vout_device *vout)
232
-{
233
- int i, numbuffers;
234
-
235
- /* Allocate memory for the buffers */
236
- numbuffers = (vout->vid) ? video2_numbuffers : video1_numbuffers;
237
- vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize;
238
-
239
- for (i = 0; i < numbuffers; i++) {
240
- omap_vout_free_buffer(vout->buf_virt_addr[i],
241
- vout->buffer_size);
242
- vout->buf_phy_addr[i] = 0;
243
- vout->buf_virt_addr[i] = 0;
244
- }
245169 }
246170
247171 /*
....@@ -513,7 +437,7 @@
513437 }
514438
515439 static int omapvid_handle_interlace_display(struct omap_vout_device *vout,
516
- unsigned int irqstatus, struct timeval timevalue)
440
+ unsigned int irqstatus, u64 ts)
517441 {
518442 u32 fid;
519443
....@@ -537,9 +461,9 @@
537461 if (vout->cur_frm == vout->next_frm)
538462 goto err;
539463
540
- vout->cur_frm->ts = timevalue;
541
- vout->cur_frm->state = VIDEOBUF_DONE;
542
- wake_up_interruptible(&vout->cur_frm->done);
464
+ vout->cur_frm->vbuf.vb2_buf.timestamp = ts;
465
+ vout->cur_frm->vbuf.sequence = vout->sequence++;
466
+ vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
543467 vout->cur_frm = vout->next_frm;
544468 } else {
545469 if (list_empty(&vout->dma_queue) ||
....@@ -557,13 +481,10 @@
557481 int ret, fid, mgr_id;
558482 u32 addr, irq;
559483 struct omap_overlay *ovl;
560
- struct timeval timevalue;
484
+ u64 ts;
561485 struct omapvideo_info *ovid;
562486 struct omap_dss_device *cur_display;
563487 struct omap_vout_device *vout = (struct omap_vout_device *)arg;
564
-
565
- if (!vout->streaming)
566
- return;
567488
568489 ovid = &vout->vid_info;
569490 ovl = ovid->overlays[0];
....@@ -577,7 +498,7 @@
577498 return;
578499
579500 spin_lock(&vout->vbq_lock);
580
- v4l2_get_timestamp(&timevalue);
501
+ ts = ktime_get_ns();
581502
582503 switch (cur_display->type) {
583504 case OMAP_DISPLAY_TYPE_DSI:
....@@ -595,7 +516,7 @@
595516 break;
596517 case OMAP_DISPLAY_TYPE_VENC:
597518 fid = omapvid_handle_interlace_display(vout, irqstatus,
598
- timevalue);
519
+ ts);
599520 if (!fid)
600521 goto vout_isr_err;
601522 break;
....@@ -608,9 +529,9 @@
608529 }
609530
610531 if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
611
- vout->cur_frm->ts = timevalue;
612
- vout->cur_frm->state = VIDEOBUF_DONE;
613
- wake_up_interruptible(&vout->cur_frm->done);
532
+ vout->cur_frm->vbuf.vb2_buf.timestamp = ts;
533
+ vout->cur_frm->vbuf.sequence = vout->sequence++;
534
+ vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
614535 vout->cur_frm = vout->next_frm;
615536 }
616537
....@@ -619,12 +540,10 @@
619540 goto vout_isr_err;
620541
621542 vout->next_frm = list_entry(vout->dma_queue.next,
622
- struct videobuf_buffer, queue);
543
+ struct omap_vout_buffer, queue);
623544 list_del(&vout->next_frm->queue);
624545
625
- vout->next_frm->state = VIDEOBUF_ACTIVE;
626
-
627
- addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
546
+ addr = (unsigned long)vout->queued_buf_addr[vout->next_frm->vbuf.vb2_buf.index]
628547 + vout->cropped_offset;
629548
630549 /* First save the configuration in ovelray structure */
....@@ -644,394 +563,6 @@
644563 spin_unlock(&vout->vbq_lock);
645564 }
646565
647
-/* Video buffer call backs */
648
-
649
-/*
650
- * Buffer setup function is called by videobuf layer when REQBUF ioctl is
651
- * called. This is used to setup buffers and return size and count of
652
- * buffers allocated. After the call to this buffer, videobuf layer will
653
- * setup buffer queue depending on the size and count of buffers
654
- */
655
-static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
656
- unsigned int *size)
657
-{
658
- int startindex = 0, i, j;
659
- u32 phy_addr = 0, virt_addr = 0;
660
- struct omap_vout_device *vout = q->priv_data;
661
- struct omapvideo_info *ovid = &vout->vid_info;
662
- int vid_max_buf_size;
663
-
664
- if (!vout)
665
- return -EINVAL;
666
-
667
- vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize :
668
- video2_bufsize;
669
-
670
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
671
- return -EINVAL;
672
-
673
- startindex = (vout->vid == OMAP_VIDEO1) ?
674
- video1_numbuffers : video2_numbuffers;
675
- if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
676
- *count = startindex;
677
-
678
- if (ovid->rotation_type == VOUT_ROT_VRFB) {
679
- if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
680
- return -ENOMEM;
681
- }
682
-
683
- if (V4L2_MEMORY_MMAP != vout->memory)
684
- return 0;
685
-
686
- /* Now allocated the V4L2 buffers */
687
- *size = PAGE_ALIGN(vout->pix.width * vout->pix.height * vout->bpp);
688
- startindex = (vout->vid == OMAP_VIDEO1) ?
689
- video1_numbuffers : video2_numbuffers;
690
-
691
- /* Check the size of the buffer */
692
- if (*size > vid_max_buf_size) {
693
- v4l2_err(&vout->vid_dev->v4l2_dev,
694
- "buffer allocation mismatch [%u] [%u]\n",
695
- *size, vout->buffer_size);
696
- return -ENOMEM;
697
- }
698
-
699
- for (i = startindex; i < *count; i++) {
700
- vout->buffer_size = *size;
701
-
702
- virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
703
- &phy_addr);
704
- if (!virt_addr) {
705
- if (ovid->rotation_type == VOUT_ROT_NONE)
706
- break;
707
-
708
- if (!is_rotation_enabled(vout))
709
- break;
710
-
711
- /* Free the VRFB buffers if no space for V4L2 buffers */
712
- for (j = i; j < *count; j++) {
713
- omap_vout_free_buffer(vout->smsshado_virt_addr[j],
714
- vout->smsshado_size);
715
- vout->smsshado_virt_addr[j] = 0;
716
- vout->smsshado_phy_addr[j] = 0;
717
- }
718
- }
719
- vout->buf_virt_addr[i] = virt_addr;
720
- vout->buf_phy_addr[i] = phy_addr;
721
- }
722
- *count = vout->buffer_allocated = i;
723
-
724
- return 0;
725
-}
726
-
727
-/*
728
- * Free the V4L2 buffers additionally allocated than default
729
- * number of buffers
730
- */
731
-static void omap_vout_free_extra_buffers(struct omap_vout_device *vout)
732
-{
733
- int num_buffers = 0, i;
734
-
735
- num_buffers = (vout->vid == OMAP_VIDEO1) ?
736
- video1_numbuffers : video2_numbuffers;
737
-
738
- for (i = num_buffers; i < vout->buffer_allocated; i++) {
739
- if (vout->buf_virt_addr[i])
740
- omap_vout_free_buffer(vout->buf_virt_addr[i],
741
- vout->buffer_size);
742
-
743
- vout->buf_virt_addr[i] = 0;
744
- vout->buf_phy_addr[i] = 0;
745
- }
746
- vout->buffer_allocated = num_buffers;
747
-}
748
-
749
-/*
750
- * This function will be called when VIDIOC_QBUF ioctl is called.
751
- * It prepare buffers before give out for the display. This function
752
- * converts user space virtual address into physical address if userptr memory
753
- * exchange mechanism is used. If rotation is enabled, it copies entire
754
- * buffer into VRFB memory space before giving it to the DSS.
755
- */
756
-static int omap_vout_buffer_prepare(struct videobuf_queue *q,
757
- struct videobuf_buffer *vb,
758
- enum v4l2_field field)
759
-{
760
- struct omap_vout_device *vout = q->priv_data;
761
- struct omapvideo_info *ovid = &vout->vid_info;
762
-
763
- if (VIDEOBUF_NEEDS_INIT == vb->state) {
764
- vb->width = vout->pix.width;
765
- vb->height = vout->pix.height;
766
- vb->size = vb->width * vb->height * vout->bpp;
767
- vb->field = field;
768
- }
769
- vb->state = VIDEOBUF_PREPARED;
770
- /* if user pointer memory mechanism is used, get the physical
771
- * address of the buffer
772
- */
773
- if (V4L2_MEMORY_USERPTR == vb->memory) {
774
- int ret;
775
-
776
- if (0 == vb->baddr)
777
- return -EINVAL;
778
- /* Physical address */
779
- ret = omap_vout_get_userptr(vb, vb->baddr,
780
- (u32 *)&vout->queued_buf_addr[vb->i]);
781
- if (ret < 0)
782
- return ret;
783
- } else {
784
- unsigned long addr, dma_addr;
785
- unsigned long size;
786
-
787
- addr = (unsigned long) vout->buf_virt_addr[vb->i];
788
- size = (unsigned long) vb->size;
789
-
790
- dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr,
791
- size, DMA_TO_DEVICE);
792
- if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr))
793
- v4l2_err(&vout->vid_dev->v4l2_dev,
794
- "dma_map_single failed\n");
795
-
796
- vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i];
797
- }
798
-
799
- if (ovid->rotation_type == VOUT_ROT_VRFB)
800
- return omap_vout_prepare_vrfb(vout, vb);
801
- else
802
- return 0;
803
-}
804
-
805
-/*
806
- * Buffer queue function will be called from the videobuf layer when _QBUF
807
- * ioctl is called. It is used to enqueue buffer, which is ready to be
808
- * displayed.
809
- */
810
-static void omap_vout_buffer_queue(struct videobuf_queue *q,
811
- struct videobuf_buffer *vb)
812
-{
813
- struct omap_vout_device *vout = q->priv_data;
814
-
815
- /* Driver is also maintainig a queue. So enqueue buffer in the driver
816
- * queue */
817
- list_add_tail(&vb->queue, &vout->dma_queue);
818
-
819
- vb->state = VIDEOBUF_QUEUED;
820
-}
821
-
822
-/*
823
- * Buffer release function is called from videobuf layer to release buffer
824
- * which are already allocated
825
- */
826
-static void omap_vout_buffer_release(struct videobuf_queue *q,
827
- struct videobuf_buffer *vb)
828
-{
829
- vb->state = VIDEOBUF_NEEDS_INIT;
830
- if (vb->memory == V4L2_MEMORY_USERPTR && vb->priv) {
831
- struct frame_vector *vec = vb->priv;
832
-
833
- put_vaddr_frames(vec);
834
- frame_vector_destroy(vec);
835
- }
836
-}
837
-
838
-/*
839
- * File operations
840
- */
841
-static __poll_t omap_vout_poll(struct file *file,
842
- struct poll_table_struct *wait)
843
-{
844
- struct omap_vout_device *vout = file->private_data;
845
- struct videobuf_queue *q = &vout->vbq;
846
-
847
- return videobuf_poll_stream(file, q, wait);
848
-}
849
-
850
-static void omap_vout_vm_open(struct vm_area_struct *vma)
851
-{
852
- struct omap_vout_device *vout = vma->vm_private_data;
853
-
854
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
855
- "vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
856
- vout->mmap_count++;
857
-}
858
-
859
-static void omap_vout_vm_close(struct vm_area_struct *vma)
860
-{
861
- struct omap_vout_device *vout = vma->vm_private_data;
862
-
863
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
864
- "vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
865
- vout->mmap_count--;
866
-}
867
-
868
-static const struct vm_operations_struct omap_vout_vm_ops = {
869
- .open = omap_vout_vm_open,
870
- .close = omap_vout_vm_close,
871
-};
872
-
873
-static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
874
-{
875
- int i;
876
- void *pos;
877
- unsigned long start = vma->vm_start;
878
- unsigned long size = (vma->vm_end - vma->vm_start);
879
- struct omap_vout_device *vout = file->private_data;
880
- struct videobuf_queue *q = &vout->vbq;
881
-
882
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
883
- " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__,
884
- vma->vm_pgoff, vma->vm_start, vma->vm_end);
885
-
886
- /* look for the buffer to map */
887
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
888
- if (NULL == q->bufs[i])
889
- continue;
890
- if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)
891
- continue;
892
- if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))
893
- break;
894
- }
895
-
896
- if (VIDEO_MAX_FRAME == i) {
897
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
898
- "offset invalid [offset=0x%lx]\n",
899
- (vma->vm_pgoff << PAGE_SHIFT));
900
- return -EINVAL;
901
- }
902
- /* Check the size of the buffer */
903
- if (size > vout->buffer_size) {
904
- v4l2_err(&vout->vid_dev->v4l2_dev,
905
- "insufficient memory [%lu] [%u]\n",
906
- size, vout->buffer_size);
907
- return -ENOMEM;
908
- }
909
-
910
- q->bufs[i]->baddr = vma->vm_start;
911
-
912
- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
913
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
914
- vma->vm_ops = &omap_vout_vm_ops;
915
- vma->vm_private_data = (void *) vout;
916
- pos = (void *)vout->buf_virt_addr[i];
917
- vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
918
- while (size > 0) {
919
- unsigned long pfn;
920
- pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT;
921
- if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
922
- return -EAGAIN;
923
- start += PAGE_SIZE;
924
- pos += PAGE_SIZE;
925
- size -= PAGE_SIZE;
926
- }
927
- vout->mmap_count++;
928
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
929
-
930
- return 0;
931
-}
932
-
933
-static int omap_vout_release(struct file *file)
934
-{
935
- unsigned int ret, i;
936
- struct videobuf_queue *q;
937
- struct omapvideo_info *ovid;
938
- struct omap_vout_device *vout = file->private_data;
939
-
940
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
941
- ovid = &vout->vid_info;
942
-
943
- if (!vout)
944
- return 0;
945
-
946
- q = &vout->vbq;
947
- /* Disable all the overlay managers connected with this interface */
948
- for (i = 0; i < ovid->num_overlays; i++) {
949
- struct omap_overlay *ovl = ovid->overlays[i];
950
- struct omap_dss_device *dssdev = ovl->get_device(ovl);
951
-
952
- if (dssdev)
953
- ovl->disable(ovl);
954
- }
955
- /* Turn off the pipeline */
956
- ret = omapvid_apply_changes(vout);
957
- if (ret)
958
- v4l2_warn(&vout->vid_dev->v4l2_dev,
959
- "Unable to apply changes\n");
960
-
961
- /* Free all buffers */
962
- omap_vout_free_extra_buffers(vout);
963
-
964
- /* Free the VRFB buffers only if they are allocated
965
- * during reqbufs. Don't free if init time allocated
966
- */
967
- if (ovid->rotation_type == VOUT_ROT_VRFB) {
968
- if (!vout->vrfb_static_allocation)
969
- omap_vout_free_vrfb_buffers(vout);
970
- }
971
- videobuf_mmap_free(q);
972
-
973
- /* Even if apply changes fails we should continue
974
- freeing allocated memory */
975
- if (vout->streaming) {
976
- u32 mask = 0;
977
-
978
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
979
- DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2;
980
- omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
981
- vout->streaming = false;
982
-
983
- videobuf_streamoff(q);
984
- videobuf_queue_cancel(q);
985
- }
986
-
987
- if (vout->mmap_count != 0)
988
- vout->mmap_count = 0;
989
-
990
- vout->opened -= 1;
991
- file->private_data = NULL;
992
-
993
- if (vout->buffer_allocated)
994
- videobuf_mmap_free(q);
995
-
996
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
997
- return ret;
998
-}
999
-
1000
-static int omap_vout_open(struct file *file)
1001
-{
1002
- struct videobuf_queue *q;
1003
- struct omap_vout_device *vout = NULL;
1004
-
1005
- vout = video_drvdata(file);
1006
-
1007
- if (vout == NULL)
1008
- return -ENODEV;
1009
-
1010
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
1011
-
1012
- /* for now, we only support single open */
1013
- if (vout->opened)
1014
- return -EBUSY;
1015
-
1016
- vout->opened += 1;
1017
-
1018
- file->private_data = vout;
1019
- vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1020
-
1021
- q = &vout->vbq;
1022
- video_vbq_ops.buf_setup = omap_vout_buffer_setup;
1023
- video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
1024
- video_vbq_ops.buf_release = omap_vout_buffer_release;
1025
- video_vbq_ops.buf_queue = omap_vout_buffer_queue;
1026
- spin_lock_init(&vout->vbq_lock);
1027
-
1028
- videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
1029
- &vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
1030
- sizeof(struct videobuf_buffer), vout, NULL);
1031
-
1032
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1033
- return 0;
1034
-}
1035566
1036567 /*
1037568 * V4L2 ioctls
....@@ -1039,15 +570,12 @@
1039570 static int vidioc_querycap(struct file *file, void *fh,
1040571 struct v4l2_capability *cap)
1041572 {
1042
- struct omap_vout_device *vout = fh;
573
+ struct omap_vout_device *vout = video_drvdata(file);
1043574
1044
- strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
1045
- strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
1046
- cap->bus_info[0] = '\0';
1047
- cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
1048
- V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
1049
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1050
-
575
+ strscpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
576
+ strscpy(cap->card, vout->vfd->name, sizeof(cap->card));
577
+ snprintf(cap->bus_info, sizeof(cap->bus_info),
578
+ "platform:%s.%d", VOUT_NAME, vout->vid);
1051579 return 0;
1052580 }
1053581
....@@ -1060,8 +588,6 @@
1060588 return -EINVAL;
1061589
1062590 fmt->flags = omap_formats[index].flags;
1063
- strlcpy(fmt->description, omap_formats[index].description,
1064
- sizeof(fmt->description));
1065591 fmt->pixelformat = omap_formats[index].pixelformat;
1066592
1067593 return 0;
....@@ -1070,7 +596,7 @@
1070596 static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
1071597 struct v4l2_format *f)
1072598 {
1073
- struct omap_vout_device *vout = fh;
599
+ struct omap_vout_device *vout = video_drvdata(file);
1074600
1075601 f->fmt.pix = vout->pix;
1076602 return 0;
....@@ -1083,7 +609,7 @@
1083609 struct omap_overlay *ovl;
1084610 struct omapvideo_info *ovid;
1085611 struct omap_video_timings *timing;
1086
- struct omap_vout_device *vout = fh;
612
+ struct omap_vout_device *vout = video_drvdata(file);
1087613 struct omap_dss_device *dssdev;
1088614
1089615 ovid = &vout->vid_info;
....@@ -1110,13 +636,11 @@
1110636 struct omap_overlay *ovl;
1111637 struct omapvideo_info *ovid;
1112638 struct omap_video_timings *timing;
1113
- struct omap_vout_device *vout = fh;
639
+ struct omap_vout_device *vout = video_drvdata(file);
1114640 struct omap_dss_device *dssdev;
1115641
1116
- if (vout->streaming)
642
+ if (vb2_is_busy(&vout->vq))
1117643 return -EBUSY;
1118
-
1119
- mutex_lock(&vout->lock);
1120644
1121645 ovid = &vout->vid_info;
1122646 ovl = ovid->overlays[0];
....@@ -1129,7 +653,7 @@
1129653 }
1130654 timing = &dssdev->panel.timings;
1131655
1132
- /* We dont support RGB24-packed mode if vrfb rotation
656
+ /* We don't support RGB24-packed mode if vrfb rotation
1133657 * is enabled*/
1134658 if ((is_rotation_enabled(vout)) &&
1135659 f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
....@@ -1147,7 +671,7 @@
1147671 vout->fbuf.fmt.width = timing->x_res;
1148672 }
1149673
1150
- /* change to samller size is OK */
674
+ /* change to smaller size is OK */
1151675
1152676 bpp = omap_vout_try_format(&f->fmt.pix);
1153677 f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp;
....@@ -1168,7 +692,6 @@
1168692 ret = 0;
1169693
1170694 s_fmt_vid_out_exit:
1171
- mutex_unlock(&vout->lock);
1172695 return ret;
1173696 }
1174697
....@@ -1176,7 +699,7 @@
1176699 struct v4l2_format *f)
1177700 {
1178701 int ret = 0;
1179
- struct omap_vout_device *vout = fh;
702
+ struct omap_vout_device *vout = video_drvdata(file);
1180703 struct omap_overlay *ovl;
1181704 struct omapvideo_info *ovid;
1182705 struct v4l2_window *win = &f->fmt.win;
....@@ -1186,12 +709,8 @@
1186709
1187710 ret = omap_vout_try_window(&vout->fbuf, win);
1188711
1189
- if (!ret) {
1190
- if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
1191
- win->global_alpha = 255;
1192
- else
1193
- win->global_alpha = f->fmt.win.global_alpha;
1194
- }
712
+ if (!ret && !(ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA))
713
+ win->global_alpha = 0;
1195714
1196715 return ret;
1197716 }
....@@ -1202,35 +721,53 @@
1202721 int ret = 0;
1203722 struct omap_overlay *ovl;
1204723 struct omapvideo_info *ovid;
1205
- struct omap_vout_device *vout = fh;
724
+ struct omap_vout_device *vout = video_drvdata(file);
1206725 struct v4l2_window *win = &f->fmt.win;
1207726
1208
- mutex_lock(&vout->lock);
1209727 ovid = &vout->vid_info;
1210728 ovl = ovid->overlays[0];
1211729
1212730 ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
1213731 if (!ret) {
1214
- /* Video1 plane does not support global alpha on OMAP3 */
1215
- if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
1216
- vout->win.global_alpha = 255;
1217
- else
1218
- vout->win.global_alpha = f->fmt.win.global_alpha;
732
+ enum omap_dss_trans_key_type key_type =
733
+ OMAP_DSS_COLOR_KEY_GFX_DST;
734
+ int enable;
1219735
1220
- vout->win.chromakey = f->fmt.win.chromakey;
736
+ /* Video1 plane does not support global alpha on OMAP3 */
737
+ if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA)
738
+ vout->win.global_alpha = win->global_alpha;
739
+ else
740
+ win->global_alpha = 0;
741
+ if (vout->fbuf.flags & (V4L2_FBUF_FLAG_CHROMAKEY |
742
+ V4L2_FBUF_FLAG_SRC_CHROMAKEY))
743
+ enable = 1;
744
+ else
745
+ enable = 0;
746
+ if (vout->fbuf.flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)
747
+ key_type = OMAP_DSS_COLOR_KEY_VID_SRC;
748
+
749
+ if (ovl->manager && ovl->manager->get_manager_info &&
750
+ ovl->manager->set_manager_info) {
751
+ struct omap_overlay_manager_info info;
752
+
753
+ ovl->manager->get_manager_info(ovl->manager, &info);
754
+ info.trans_enabled = enable;
755
+ info.trans_key_type = key_type;
756
+ info.trans_key = vout->win.chromakey;
757
+
758
+ if (ovl->manager->set_manager_info(ovl->manager, &info))
759
+ return -EINVAL;
760
+ }
1221761 }
1222
- mutex_unlock(&vout->lock);
1223762 return ret;
1224763 }
1225764
1226765 static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
1227766 struct v4l2_format *f)
1228767 {
1229
- u32 key_value = 0;
1230768 struct omap_overlay *ovl;
1231769 struct omapvideo_info *ovid;
1232
- struct omap_vout_device *vout = fh;
1233
- struct omap_overlay_manager_info info;
770
+ struct omap_vout_device *vout = video_drvdata(file);
1234771 struct v4l2_window *win = &f->fmt.win;
1235772
1236773 ovid = &vout->vid_info;
....@@ -1238,19 +775,20 @@
1238775
1239776 win->w = vout->win.w;
1240777 win->field = vout->win.field;
1241
- win->global_alpha = vout->win.global_alpha;
1242
-
1243
- if (ovl->manager && ovl->manager->get_manager_info) {
1244
- ovl->manager->get_manager_info(ovl->manager, &info);
1245
- key_value = info.trans_key;
1246
- }
1247
- win->chromakey = key_value;
778
+ win->chromakey = vout->win.chromakey;
779
+ if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA)
780
+ win->global_alpha = vout->win.global_alpha;
781
+ else
782
+ win->global_alpha = 0;
783
+ win->clips = NULL;
784
+ win->clipcount = 0;
785
+ win->bitmap = NULL;
1248786 return 0;
1249787 }
1250788
1251789 static int vidioc_g_selection(struct file *file, void *fh, struct v4l2_selection *sel)
1252790 {
1253
- struct omap_vout_device *vout = fh;
791
+ struct omap_vout_device *vout = video_drvdata(file);
1254792 struct v4l2_pix_format *pix = &vout->pix;
1255793
1256794 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
....@@ -1277,7 +815,7 @@
1277815 static int vidioc_s_selection(struct file *file, void *fh, struct v4l2_selection *sel)
1278816 {
1279817 int ret = -EINVAL;
1280
- struct omap_vout_device *vout = fh;
818
+ struct omap_vout_device *vout = video_drvdata(file);
1281819 struct omapvideo_info *ovid;
1282820 struct omap_overlay *ovl;
1283821 struct omap_video_timings *timing;
....@@ -1289,10 +827,9 @@
1289827 if (sel->target != V4L2_SEL_TGT_CROP)
1290828 return -EINVAL;
1291829
1292
- if (vout->streaming)
830
+ if (vb2_is_busy(&vout->vq))
1293831 return -EBUSY;
1294832
1295
- mutex_lock(&vout->lock);
1296833 ovid = &vout->vid_info;
1297834 ovl = ovid->overlays[0];
1298835 /* get the display device attached to the overlay */
....@@ -1317,7 +854,6 @@
1317854 &vout->fbuf, &sel->r);
1318855
1319856 s_crop_err:
1320
- mutex_unlock(&vout->lock);
1321857 return ret;
1322858 }
1323859
....@@ -1334,26 +870,21 @@
1334870
1335871 ovid = &vout->vid_info;
1336872
1337
- mutex_lock(&vout->lock);
1338873 if (rotation && ovid->rotation_type == VOUT_ROT_NONE) {
1339
- mutex_unlock(&vout->lock);
1340874 ret = -ERANGE;
1341875 break;
1342876 }
1343877
1344878 if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1345
- mutex_unlock(&vout->lock);
1346879 ret = -EINVAL;
1347880 break;
1348881 }
1349882
1350883 if (v4l2_rot_to_dss_rot(rotation, &vout->rotation,
1351884 vout->mirror)) {
1352
- mutex_unlock(&vout->lock);
1353885 ret = -EINVAL;
1354886 break;
1355887 }
1356
- mutex_unlock(&vout->lock);
1357888 break;
1358889 }
1359890 case V4L2_CID_BG_COLOR:
....@@ -1364,9 +895,7 @@
1364895
1365896 ovl = vout->vid_info.overlays[0];
1366897
1367
- mutex_lock(&vout->lock);
1368898 if (!ovl->manager || !ovl->manager->get_manager_info) {
1369
- mutex_unlock(&vout->lock);
1370899 ret = -EINVAL;
1371900 break;
1372901 }
....@@ -1374,11 +903,9 @@
1374903 ovl->manager->get_manager_info(ovl->manager, &info);
1375904 info.default_color = color;
1376905 if (ovl->manager->set_manager_info(ovl->manager, &info)) {
1377
- mutex_unlock(&vout->lock);
1378906 ret = -EINVAL;
1379907 break;
1380908 }
1381
- mutex_unlock(&vout->lock);
1382909 break;
1383910 }
1384911 case V4L2_CID_VFLIP:
....@@ -1388,20 +915,16 @@
1388915
1389916 ovid = &vout->vid_info;
1390917
1391
- mutex_lock(&vout->lock);
1392918 if (mirror && ovid->rotation_type == VOUT_ROT_NONE) {
1393
- mutex_unlock(&vout->lock);
1394919 ret = -ERANGE;
1395920 break;
1396921 }
1397922
1398923 if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1399
- mutex_unlock(&vout->lock);
1400924 ret = -EINVAL;
1401925 break;
1402926 }
1403927 vout->mirror = mirror;
1404
- mutex_unlock(&vout->lock);
1405928 break;
1406929 }
1407930 default:
....@@ -1414,185 +937,94 @@
1414937 .s_ctrl = omap_vout_s_ctrl,
1415938 };
1416939
1417
-static int vidioc_reqbufs(struct file *file, void *fh,
1418
- struct v4l2_requestbuffers *req)
940
+static int omap_vout_vb2_queue_setup(struct vb2_queue *vq,
941
+ unsigned int *nbufs,
942
+ unsigned int *num_planes, unsigned int sizes[],
943
+ struct device *alloc_devs[])
1419944 {
1420
- int ret = 0;
1421
- unsigned int i, num_buffers = 0;
1422
- struct omap_vout_device *vout = fh;
1423
- struct videobuf_queue *q = &vout->vbq;
945
+ struct omap_vout_device *vout = vb2_get_drv_priv(vq);
946
+ int size = vout->pix.sizeimage;
1424947
1425
- if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1426
- return -EINVAL;
1427
- /* if memory is not mmp or userptr
1428
- return error */
1429
- if ((V4L2_MEMORY_MMAP != req->memory) &&
1430
- (V4L2_MEMORY_USERPTR != req->memory))
1431
- return -EINVAL;
1432
-
1433
- mutex_lock(&vout->lock);
1434
- /* Cannot be requested when streaming is on */
1435
- if (vout->streaming) {
1436
- ret = -EBUSY;
1437
- goto reqbuf_err;
1438
- }
1439
-
1440
- /* If buffers are already allocated free them */
1441
- if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) {
1442
- if (vout->mmap_count) {
1443
- ret = -EBUSY;
1444
- goto reqbuf_err;
1445
- }
1446
- num_buffers = (vout->vid == OMAP_VIDEO1) ?
1447
- video1_numbuffers : video2_numbuffers;
1448
- for (i = num_buffers; i < vout->buffer_allocated; i++) {
1449
- omap_vout_free_buffer(vout->buf_virt_addr[i],
1450
- vout->buffer_size);
1451
- vout->buf_virt_addr[i] = 0;
1452
- vout->buf_phy_addr[i] = 0;
1453
- }
1454
- vout->buffer_allocated = num_buffers;
1455
- videobuf_mmap_free(q);
1456
- } else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) {
1457
- if (vout->buffer_allocated) {
1458
- videobuf_mmap_free(q);
1459
- for (i = 0; i < vout->buffer_allocated; i++) {
1460
- kfree(q->bufs[i]);
1461
- q->bufs[i] = NULL;
1462
- }
1463
- vout->buffer_allocated = 0;
1464
- }
1465
- }
1466
-
1467
- /*store the memory type in data structure */
1468
- vout->memory = req->memory;
1469
-
1470
- INIT_LIST_HEAD(&vout->dma_queue);
1471
-
1472
- /* call videobuf_reqbufs api */
1473
- ret = videobuf_reqbufs(q, req);
1474
- if (ret < 0)
1475
- goto reqbuf_err;
1476
-
1477
- vout->buffer_allocated = req->count;
1478
-
1479
-reqbuf_err:
1480
- mutex_unlock(&vout->lock);
1481
- return ret;
1482
-}
1483
-
1484
-static int vidioc_querybuf(struct file *file, void *fh,
1485
- struct v4l2_buffer *b)
1486
-{
1487
- struct omap_vout_device *vout = fh;
1488
-
1489
- return videobuf_querybuf(&vout->vbq, b);
1490
-}
1491
-
1492
-static int vidioc_qbuf(struct file *file, void *fh,
1493
- struct v4l2_buffer *buffer)
1494
-{
1495
- struct omap_vout_device *vout = fh;
1496
- struct videobuf_queue *q = &vout->vbq;
1497
-
1498
- if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) ||
1499
- (buffer->index >= vout->buffer_allocated) ||
1500
- (q->bufs[buffer->index]->memory != buffer->memory)) {
1501
- return -EINVAL;
1502
- }
1503
- if (V4L2_MEMORY_USERPTR == buffer->memory) {
1504
- if ((buffer->length < vout->pix.sizeimage) ||
1505
- (0 == buffer->m.userptr)) {
948
+ if (is_rotation_enabled(vout) && vq->num_buffers + *nbufs > VRFB_NUM_BUFS) {
949
+ *nbufs = VRFB_NUM_BUFS - vq->num_buffers;
950
+ if (*nbufs == 0)
1506951 return -EINVAL;
1507
- }
1508952 }
1509953
1510
- if ((is_rotation_enabled(vout)) &&
1511
- vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) {
1512
- v4l2_warn(&vout->vid_dev->v4l2_dev,
1513
- "DMA Channel not allocated for Rotation\n");
1514
- return -EINVAL;
1515
- }
954
+ if (*num_planes)
955
+ return sizes[0] < size ? -EINVAL : 0;
1516956
1517
- return videobuf_qbuf(q, buffer);
1518
-}
1519
-
1520
-static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1521
-{
1522
- struct omap_vout_device *vout = fh;
1523
- struct videobuf_queue *q = &vout->vbq;
1524
-
1525
- int ret;
1526
- u32 addr;
1527
- unsigned long size;
1528
- struct videobuf_buffer *vb;
1529
-
1530
- if (!vout->streaming)
1531
- return -EINVAL;
1532
-
1533
- ret = videobuf_dqbuf(q, b, !!(file->f_flags & O_NONBLOCK));
1534
- if (ret)
1535
- return ret;
1536
-
1537
- vb = q->bufs[b->index];
1538
-
1539
- addr = (unsigned long) vout->buf_phy_addr[vb->i];
1540
- size = (unsigned long) vb->size;
1541
- dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr,
1542
- size, DMA_TO_DEVICE);
957
+ *num_planes = 1;
958
+ sizes[0] = size;
1543959 return 0;
1544960 }
1545961
1546
-static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
962
+static int omap_vout_vb2_prepare(struct vb2_buffer *vb)
1547963 {
1548
- int ret = 0, j;
1549
- u32 addr = 0, mask = 0;
1550
- struct omap_vout_device *vout = fh;
1551
- struct videobuf_queue *q = &vout->vbq;
964
+ struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue);
1552965 struct omapvideo_info *ovid = &vout->vid_info;
966
+ struct omap_vout_buffer *voutbuf = vb2_to_omap_vout_buffer(vb);
967
+ dma_addr_t buf_phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1553968
1554
- mutex_lock(&vout->lock);
1555
-
1556
- if (vout->streaming) {
1557
- ret = -EBUSY;
1558
- goto streamon_err;
969
+ if (vb2_plane_size(vb, 0) < vout->pix.sizeimage) {
970
+ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
971
+ "%s data will not fit into plane (%lu < %u)\n",
972
+ __func__, vb2_plane_size(vb, 0), vout->pix.sizeimage);
973
+ return -EINVAL;
1559974 }
1560975
1561
- ret = videobuf_streamon(q);
1562
- if (ret)
1563
- goto streamon_err;
976
+ vb2_set_plane_payload(vb, 0, vout->pix.sizeimage);
977
+ voutbuf->vbuf.field = V4L2_FIELD_NONE;
1564978
1565
- if (list_empty(&vout->dma_queue)) {
1566
- ret = -EIO;
1567
- goto streamon_err1;
1568
- }
979
+ vout->queued_buf_addr[vb->index] = (u8 *)buf_phy_addr;
980
+ if (ovid->rotation_type == VOUT_ROT_VRFB)
981
+ return omap_vout_prepare_vrfb(vout, vb);
982
+ return 0;
983
+}
984
+
985
+static void omap_vout_vb2_queue(struct vb2_buffer *vb)
986
+{
987
+ struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue);
988
+ struct omap_vout_buffer *voutbuf = vb2_to_omap_vout_buffer(vb);
989
+
990
+ list_add_tail(&voutbuf->queue, &vout->dma_queue);
991
+}
992
+
993
+static int omap_vout_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
994
+{
995
+ struct omap_vout_device *vout = vb2_get_drv_priv(vq);
996
+ struct omapvideo_info *ovid = &vout->vid_info;
997
+ struct omap_vout_buffer *buf, *tmp;
998
+ u32 addr = 0, mask = 0;
999
+ int ret, j;
15691000
15701001 /* Get the next frame from the buffer queue */
15711002 vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next,
1572
- struct videobuf_buffer, queue);
1003
+ struct omap_vout_buffer, queue);
15731004 /* Remove buffer from the buffer queue */
15741005 list_del(&vout->cur_frm->queue);
1575
- /* Mark state of the current frame to active */
1576
- vout->cur_frm->state = VIDEOBUF_ACTIVE;
15771006 /* Initialize field_id and started member */
15781007 vout->field_id = 0;
1579
-
1580
- /* set flag here. Next QBUF will start DMA */
1581
- vout->streaming = true;
1582
-
15831008 vout->first_int = 1;
1009
+ vout->sequence = 0;
15841010
15851011 if (omap_vout_calculate_offset(vout)) {
15861012 ret = -EINVAL;
1587
- goto streamon_err1;
1013
+ goto out;
15881014 }
1589
- addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i]
1015
+ if (ovid->rotation_type == VOUT_ROT_VRFB)
1016
+ if (omap_vout_vrfb_buffer_setup(vout, &count, 0)) {
1017
+ ret = -ENOMEM;
1018
+ goto out;
1019
+ }
1020
+
1021
+ addr = (unsigned long)vout->queued_buf_addr[vout->cur_frm->vbuf.vb2_buf.index]
15901022 + vout->cropped_offset;
15911023
15921024 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
15931025 | DISPC_IRQ_VSYNC2;
15941026
1595
- /* First save the configuration in ovelray structure */
1027
+ /* First save the configuration in overlay structure */
15961028 ret = omapvid_init(vout, addr);
15971029 if (ret) {
15981030 v4l2_err(&vout->vid_dev->v4l2_dev,
....@@ -1617,28 +1049,9 @@
16171049 goto streamon_err1;
16181050 }
16191051 }
1620
-
1621
- ret = 0;
1052
+ return 0;
16221053
16231054 streamon_err1:
1624
- if (ret)
1625
- ret = videobuf_streamoff(q);
1626
-streamon_err:
1627
- mutex_unlock(&vout->lock);
1628
- return ret;
1629
-}
1630
-
1631
-static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1632
-{
1633
- u32 mask = 0;
1634
- int ret = 0, j;
1635
- struct omap_vout_device *vout = fh;
1636
- struct omapvideo_info *ovid = &vout->vid_info;
1637
-
1638
- if (!vout->streaming)
1639
- return -EINVAL;
1640
-
1641
- vout->streaming = false;
16421055 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
16431056 | DISPC_IRQ_VSYNC2;
16441057
....@@ -1651,17 +1064,52 @@
16511064 if (dssdev)
16521065 ovl->disable(ovl);
16531066 }
1654
-
16551067 /* Turn of the pipeline */
1656
- ret = omapvid_apply_changes(vout);
1657
- if (ret)
1068
+ if (omapvid_apply_changes(vout))
16581069 v4l2_err(&vout->vid_dev->v4l2_dev,
16591070 "failed to change mode in streamoff\n");
16601071
1661
- INIT_LIST_HEAD(&vout->dma_queue);
1662
- ret = videobuf_streamoff(&vout->vbq);
1663
-
1072
+out:
1073
+ vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED);
1074
+ list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) {
1075
+ list_del(&buf->queue);
1076
+ vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED);
1077
+ }
16641078 return ret;
1079
+}
1080
+
1081
+static void omap_vout_vb2_stop_streaming(struct vb2_queue *vq)
1082
+{
1083
+ struct omap_vout_device *vout = vb2_get_drv_priv(vq);
1084
+ struct omapvideo_info *ovid = &vout->vid_info;
1085
+ struct omap_vout_buffer *buf, *tmp;
1086
+ u32 mask = 0;
1087
+ int j;
1088
+
1089
+ mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1090
+ | DISPC_IRQ_VSYNC2;
1091
+
1092
+ omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
1093
+
1094
+ for (j = 0; j < ovid->num_overlays; j++) {
1095
+ struct omap_overlay *ovl = ovid->overlays[j];
1096
+ struct omap_dss_device *dssdev = ovl->get_device(ovl);
1097
+
1098
+ if (dssdev)
1099
+ ovl->disable(ovl);
1100
+ }
1101
+ /* Turn of the pipeline */
1102
+ if (omapvid_apply_changes(vout))
1103
+ v4l2_err(&vout->vid_dev->v4l2_dev,
1104
+ "failed to change mode in streamoff\n");
1105
+
1106
+ if (vout->next_frm != vout->cur_frm)
1107
+ vb2_buffer_done(&vout->next_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
1108
+ vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
1109
+ list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) {
1110
+ list_del(&buf->queue);
1111
+ vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
1112
+ }
16651113 }
16661114
16671115 static int vidioc_s_fbuf(struct file *file, void *fh,
....@@ -1670,7 +1118,7 @@
16701118 int enable = 0;
16711119 struct omap_overlay *ovl;
16721120 struct omapvideo_info *ovid;
1673
- struct omap_vout_device *vout = fh;
1121
+ struct omap_vout_device *vout = video_drvdata(file);
16741122 struct omap_overlay_manager_info info;
16751123 enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
16761124
....@@ -1741,17 +1189,36 @@
17411189 {
17421190 struct omap_overlay *ovl;
17431191 struct omapvideo_info *ovid;
1744
- struct omap_vout_device *vout = fh;
1192
+ struct omap_vout_device *vout = video_drvdata(file);
17451193 struct omap_overlay_manager_info info;
1194
+ struct omap_video_timings *timing;
1195
+ struct omap_dss_device *dssdev;
17461196
17471197 ovid = &vout->vid_info;
17481198 ovl = ovid->overlays[0];
1199
+ /* get the display device attached to the overlay */
1200
+ dssdev = ovl->get_device(ovl);
17491201
1750
- /* The video overlay must stay within the framebuffer and can't be
1751
- positioned independently. */
1752
- a->flags = V4L2_FBUF_FLAG_OVERLAY;
1753
- a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
1754
- | V4L2_FBUF_CAP_SRC_CHROMAKEY;
1202
+ if (!dssdev)
1203
+ return -EINVAL;
1204
+
1205
+ timing = &dssdev->panel.timings;
1206
+
1207
+ vout->fbuf.fmt.height = timing->y_res;
1208
+ vout->fbuf.fmt.width = timing->x_res;
1209
+ a->fmt.field = V4L2_FIELD_NONE;
1210
+ a->fmt.colorspace = V4L2_COLORSPACE_SRGB;
1211
+ a->fmt.pixelformat = V4L2_PIX_FMT_RGBA32;
1212
+ a->fmt.height = vout->fbuf.fmt.height;
1213
+ a->fmt.width = vout->fbuf.fmt.width;
1214
+ a->fmt.bytesperline = vout->fbuf.fmt.width * 4;
1215
+ a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline;
1216
+ a->base = vout->fbuf.base;
1217
+
1218
+ a->flags = vout->fbuf.flags;
1219
+ a->capability = vout->fbuf.capability;
1220
+ a->flags &= ~(V4L2_FBUF_FLAG_SRC_CHROMAKEY | V4L2_FBUF_FLAG_CHROMAKEY |
1221
+ V4L2_FBUF_FLAG_LOCAL_ALPHA);
17551222
17561223 if (ovl->manager && ovl->manager->get_manager_info) {
17571224 ovl->manager->get_manager_info(ovl->manager, &info);
....@@ -1759,14 +1226,32 @@
17591226 a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
17601227 if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
17611228 a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1762
- }
1763
- if (ovl->manager && ovl->manager->get_manager_info) {
1764
- ovl->manager->get_manager_info(ovl->manager, &info);
17651229 if (info.partial_alpha_enabled)
17661230 a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
17671231 }
17681232
17691233 return 0;
1234
+}
1235
+
1236
+static int vidioc_enum_output(struct file *file, void *priv_fh,
1237
+ struct v4l2_output *out)
1238
+{
1239
+ if (out->index)
1240
+ return -EINVAL;
1241
+ snprintf(out->name, sizeof(out->name), "Overlay");
1242
+ out->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
1243
+ return 0;
1244
+}
1245
+
1246
+static int vidioc_g_output(struct file *file, void *priv_fh, unsigned int *i)
1247
+{
1248
+ *i = 0;
1249
+ return 0;
1250
+}
1251
+
1252
+static int vidioc_s_output(struct file *file, void *priv_fh, unsigned int i)
1253
+{
1254
+ return i ? -EINVAL : 0;
17701255 }
17711256
17721257 static const struct v4l2_ioctl_ops vout_ioctl_ops = {
....@@ -1782,21 +1267,38 @@
17821267 .vidioc_g_fmt_vid_out_overlay = vidioc_g_fmt_vid_overlay,
17831268 .vidioc_g_selection = vidioc_g_selection,
17841269 .vidioc_s_selection = vidioc_s_selection,
1785
- .vidioc_reqbufs = vidioc_reqbufs,
1786
- .vidioc_querybuf = vidioc_querybuf,
1787
- .vidioc_qbuf = vidioc_qbuf,
1788
- .vidioc_dqbuf = vidioc_dqbuf,
1789
- .vidioc_streamon = vidioc_streamon,
1790
- .vidioc_streamoff = vidioc_streamoff,
1270
+ .vidioc_enum_output = vidioc_enum_output,
1271
+ .vidioc_g_output = vidioc_g_output,
1272
+ .vidioc_s_output = vidioc_s_output,
1273
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
1274
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
1275
+ .vidioc_querybuf = vb2_ioctl_querybuf,
1276
+ .vidioc_qbuf = vb2_ioctl_qbuf,
1277
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
1278
+ .vidioc_expbuf = vb2_ioctl_expbuf,
1279
+ .vidioc_streamon = vb2_ioctl_streamon,
1280
+ .vidioc_streamoff = vb2_ioctl_streamoff,
1281
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1282
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
17911283 };
17921284
17931285 static const struct v4l2_file_operations omap_vout_fops = {
17941286 .owner = THIS_MODULE,
1795
- .poll = omap_vout_poll,
17961287 .unlocked_ioctl = video_ioctl2,
1797
- .mmap = omap_vout_mmap,
1798
- .open = omap_vout_open,
1799
- .release = omap_vout_release,
1288
+ .poll = vb2_fop_poll,
1289
+ .mmap = vb2_fop_mmap,
1290
+ .open = v4l2_fh_open,
1291
+ .release = vb2_fop_release,
1292
+};
1293
+
1294
+static const struct vb2_ops omap_vout_vb2_ops = {
1295
+ .queue_setup = omap_vout_vb2_queue_setup,
1296
+ .buf_queue = omap_vout_vb2_queue,
1297
+ .buf_prepare = omap_vout_vb2_prepare,
1298
+ .start_streaming = omap_vout_vb2_start_streaming,
1299
+ .stop_streaming = omap_vout_vb2_stop_streaming,
1300
+ .wait_prepare = vb2_ops_wait_prepare,
1301
+ .wait_finish = vb2_ops_wait_finish,
18001302 };
18011303
18021304 /* Init functions used during driver initialization */
....@@ -1808,6 +1310,8 @@
18081310 struct omap_overlay *ovl = vout->vid_info.overlays[0];
18091311 struct omap_dss_device *display = ovl->get_device(ovl);
18101312 struct v4l2_ctrl_handler *hdl;
1313
+ struct vb2_queue *vq;
1314
+ int ret;
18111315
18121316 /* set the default pix */
18131317 pix = &vout->pix;
....@@ -1818,37 +1322,48 @@
18181322
18191323 /* Default pixel format is RGB 5-6-5 */
18201324 pix->pixelformat = V4L2_PIX_FMT_RGB565;
1821
- pix->field = V4L2_FIELD_ANY;
1325
+ pix->field = V4L2_FIELD_NONE;
18221326 pix->bytesperline = pix->width * 2;
18231327 pix->sizeimage = pix->bytesperline * pix->height;
1824
- pix->colorspace = V4L2_COLORSPACE_JPEG;
1328
+ pix->colorspace = V4L2_COLORSPACE_SRGB;
18251329
18261330 vout->bpp = RGB565_BPP;
18271331 vout->fbuf.fmt.width = display->panel.timings.x_res;
18281332 vout->fbuf.fmt.height = display->panel.timings.y_res;
1333
+ vout->cropped_offset = 0;
18291334
18301335 /* Set the data structures for the overlay parameters*/
1831
- vout->win.global_alpha = 255;
1832
- vout->fbuf.flags = 0;
1336
+ vout->fbuf.flags = V4L2_FBUF_FLAG_OVERLAY;
18331337 vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
1834
- V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY;
1835
- vout->win.chromakey = 0;
1338
+ V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY |
1339
+ V4L2_FBUF_CAP_EXTERNOVERLAY;
1340
+ if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) {
1341
+ vout->win.global_alpha = 255;
1342
+ vout->fbuf.capability |= V4L2_FBUF_CAP_GLOBAL_ALPHA;
1343
+ vout->fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1344
+ } else {
1345
+ vout->win.global_alpha = 0;
1346
+ }
1347
+ vout->win.field = V4L2_FIELD_NONE;
18361348
18371349 omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
18381350
18391351 hdl = &vout->ctrl_handler;
18401352 v4l2_ctrl_handler_init(hdl, 3);
1841
- v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
1842
- V4L2_CID_ROTATE, 0, 270, 90, 0);
1353
+ if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) {
1354
+ v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
1355
+ V4L2_CID_ROTATE, 0, 270, 90, 0);
1356
+ v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
1357
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
1358
+ }
18431359 v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
18441360 V4L2_CID_BG_COLOR, 0, 0xffffff, 1, 0);
1845
- v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
1846
- V4L2_CID_VFLIP, 0, 1, 1, 0);
18471361 if (hdl->error)
18481362 return hdl->error;
18491363
18501364 vout->rotation = 0;
18511365 vout->mirror = false;
1366
+ INIT_LIST_HEAD(&vout->dma_queue);
18521367 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
18531368 vout->vrfb_bpp = 2;
18541369
....@@ -1865,49 +1380,51 @@
18651380 vfd->release = video_device_release;
18661381 vfd->ioctl_ops = &vout_ioctl_ops;
18671382
1868
- strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
1383
+ strscpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
18691384
18701385 vfd->fops = &omap_vout_fops;
18711386 vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
18721387 vfd->vfl_dir = VFL_DIR_TX;
1388
+ vfd->minor = -1;
1389
+ vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
1390
+ V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
18731391 mutex_init(&vout->lock);
18741392
1875
- vfd->minor = -1;
1876
- return 0;
1393
+ vq = &vout->vq;
1394
+ vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1395
+ vq->io_modes = VB2_MMAP | VB2_DMABUF;
1396
+ vq->drv_priv = vout;
1397
+ vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1398
+ vq->buf_struct_size = sizeof(struct omap_vout_buffer);
1399
+ vq->dev = vfd->v4l2_dev->dev;
18771400
1401
+ vq->ops = &omap_vout_vb2_ops;
1402
+ vq->mem_ops = &vb2_dma_contig_memops;
1403
+ vq->lock = &vout->lock;
1404
+ vq->min_buffers_needed = 1;
1405
+ vfd->queue = vq;
1406
+
1407
+ ret = vb2_queue_init(vq);
1408
+ if (ret) {
1409
+ v4l2_ctrl_handler_free(hdl);
1410
+ video_device_release(vfd);
1411
+ }
1412
+ return ret;
18781413 }
18791414
18801415 /* Setup video buffers */
18811416 static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
18821417 int vid_num)
18831418 {
1884
- u32 numbuffers;
1885
- int ret = 0, i;
18861419 struct omapvideo_info *ovid;
18871420 struct omap_vout_device *vout;
18881421 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
18891422 struct omap2video_device *vid_dev =
18901423 container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
1424
+ int ret = 0;
18911425
18921426 vout = vid_dev->vouts[vid_num];
18931427 ovid = &vout->vid_info;
1894
-
1895
- numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
1896
- vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
1897
- dev_info(&pdev->dev, "Buffer Size = %d\n", vout->buffer_size);
1898
-
1899
- for (i = 0; i < numbuffers; i++) {
1900
- vout->buf_virt_addr[i] =
1901
- omap_vout_alloc_buffer(vout->buffer_size,
1902
- (u32 *) &vout->buf_phy_addr[i]);
1903
- if (!vout->buf_virt_addr[i]) {
1904
- numbuffers = i;
1905
- ret = -ENOMEM;
1906
- goto free_buffers;
1907
- }
1908
- }
1909
-
1910
- vout->cropped_offset = 0;
19111428
19121429 if (ovid->rotation_type == VOUT_ROT_VRFB) {
19131430 bool static_vrfb_allocation = (vid_num == 0) ?
....@@ -1915,18 +1432,7 @@
19151432 ret = omap_vout_setup_vrfb_bufs(pdev, vid_num,
19161433 static_vrfb_allocation);
19171434 }
1918
-
19191435 return ret;
1920
-
1921
-free_buffers:
1922
- for (i = 0; i < numbuffers; i++) {
1923
- omap_vout_free_buffer(vout->buf_virt_addr[i],
1924
- vout->buffer_size);
1925
- vout->buf_virt_addr[i] = 0;
1926
- vout->buf_phy_addr[i] = 0;
1927
- }
1928
- return ret;
1929
-
19301436 }
19311437
19321438 /* Create video out devices */
....@@ -1938,6 +1444,10 @@
19381444 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
19391445 struct omap2video_device *vid_dev = container_of(v4l2_dev,
19401446 struct omap2video_device, v4l2_dev);
1447
+ struct omap_overlay *ovl = vid_dev->overlays[0];
1448
+ struct omap_overlay_info info;
1449
+
1450
+ ovl->get_overlay_info(ovl, &info);
19411451
19421452 for (k = 0; k < pdev->num_resources; k++) {
19431453
....@@ -1958,6 +1468,15 @@
19581468 vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
19591469 vout->vid_info.num_overlays = 1;
19601470 vout->vid_info.id = k + 1;
1471
+ spin_lock_init(&vout->vbq_lock);
1472
+ /*
1473
+ * Set the framebuffer base, this allows applications to find
1474
+ * the fb corresponding to this overlay.
1475
+ *
1476
+ * To be precise: fbuf.base should match smem_start of
1477
+ * struct fb_fix_screeninfo.
1478
+ */
1479
+ vout->fbuf.base = (void *)info.paddr;
19611480
19621481 /* Set VRFB as rotation_type for omap2 and omap3 */
19631482 if (omap_vout_dss_omap24xx() || omap_vout_dss_omap34xx())
....@@ -1981,7 +1500,7 @@
19811500 /* Register the Video device with V4L2
19821501 */
19831502 vfd = vout->vfd;
1984
- if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) {
1503
+ if (video_register_device(vfd, VFL_TYPE_VIDEO, -1) < 0) {
19851504 dev_err(&pdev->dev,
19861505 ": Could not register Video for Linux device\n");
19871506 vfd->minor = -1;
....@@ -2000,7 +1519,6 @@
20001519 error2:
20011520 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
20021521 omap_vout_release_vrfb(vout);
2003
- omap_vout_free_buffers(vout);
20041522 error1:
20051523 video_device_release(vfd);
20061524 error:
....@@ -2045,7 +1563,6 @@
20451563 if (vout->vrfb_static_allocation)
20461564 omap_vout_free_vrfb_buffers(vout);
20471565 }
2048
- omap_vout_free_buffers(vout);
20491566
20501567 kfree(vout);
20511568 }