Merge tag 'drm-misc-next-2021-03-03' of git://anongit.freedesktop.org/drm/drm-misc...
[linux-2.6-microblaze.git] / drivers / media / platform / omap / omap_vout.c
1 /*
2  * omap_vout.c
3  *
4  * Copyright (C) 2005-2010 Texas Instruments.
5  *
6  * This file is licensed under the terms of the GNU General Public License
7  * version 2. This program is licensed "as is" without any warranty of any
8  * kind, whether express or implied.
9  *
10  * Leveraged code from the OMAP2 camera driver
11  * Video-for-Linux (Version 2) camera capture driver for
12  * the OMAP24xx camera controller.
13  *
14  * Author: Andy Lowe (source@mvista.com)
15  *
16  * Copyright (C) 2004 MontaVista Software, Inc.
17  * Copyright (C) 2010 Texas Instruments.
18  *
19  * History:
20  * 20-APR-2006 Khasim           Modified VRFB based Rotation,
21  *                              The image data is always read from 0 degree
22  *                              view and written
23  *                              to the virtual space of desired rotation angle
24  * 4-DEC-2006  Jian             Changed to support better memory management
25  *
26  * 17-Nov-2008 Hardik           Changed driver to use video_ioctl2
27  *
28  * 23-Feb-2010 Vaibhav H        Modified to use new DSS2 interface
29  *
30  */
31
32 #include <linux/init.h>
33 #include <linux/module.h>
34 #include <linux/vmalloc.h>
35 #include <linux/sched.h>
36 #include <linux/types.h>
37 #include <linux/platform_device.h>
38 #include <linux/irq.h>
39 #include <linux/videodev2.h>
40 #include <linux/dma-mapping.h>
41 #include <linux/slab.h>
42
43 #include <media/v4l2-device.h>
44 #include <media/v4l2-ioctl.h>
45 #include <media/v4l2-event.h>
46
47 #include <video/omapvrfb.h>
48 #include <video/omapfb_dss.h>
49
50 #include "omap_voutlib.h"
51 #include "omap_voutdef.h"
52 #include "omap_vout_vrfb.h"
53
54 MODULE_AUTHOR("Texas Instruments");
55 MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
56 MODULE_LICENSE("GPL");
57
58 /* Driver Configuration macros */
59 #define VOUT_NAME               "omap_vout"
60
61 enum omap_vout_channels {
62         OMAP_VIDEO1,
63         OMAP_VIDEO2,
64 };
65
66 /* Variables configurable through module params*/
67 static bool vid1_static_vrfb_alloc;
68 static bool vid2_static_vrfb_alloc;
69 static bool debug;
70
71 /* Module parameters */
72 module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
73 MODULE_PARM_DESC(vid1_static_vrfb_alloc,
74         "Static allocation of the VRFB buffer for video1 device");
75
76 module_param(vid2_static_vrfb_alloc, bool, S_IRUGO);
77 MODULE_PARM_DESC(vid2_static_vrfb_alloc,
78         "Static allocation of the VRFB buffer for video2 device");
79
80 module_param(debug, bool, S_IRUGO);
81 MODULE_PARM_DESC(debug, "Debug level (0-1)");
82
83 /* list of image formats supported by OMAP2 video pipelines */
84 static const struct v4l2_fmtdesc omap_formats[] = {
85         {
86                 /* Note:  V4L2 defines RGB565 as:
87                  *
88                  *      Byte 0                    Byte 1
89                  *      g2 g1 g0 r4 r3 r2 r1 r0   b4 b3 b2 b1 b0 g5 g4 g3
90                  *
91                  * We interpret RGB565 as:
92                  *
93                  *      Byte 0                    Byte 1
94                  *      g2 g1 g0 b4 b3 b2 b1 b0   r4 r3 r2 r1 r0 g5 g4 g3
95                  */
96                 .pixelformat = V4L2_PIX_FMT_RGB565,
97         },
98         {
99                 /* Note:  V4L2 defines RGB32 as: RGB-8-8-8-8  we use
100                  *  this for RGB24 unpack mode, the last 8 bits are ignored
101                  * */
102                 .pixelformat = V4L2_PIX_FMT_RGB32,
103         },
104         {
105                 /* Note:  V4L2 defines RGB24 as: RGB-8-8-8  we use
106                  *        this for RGB24 packed mode
107                  *
108                  */
109                 .pixelformat = V4L2_PIX_FMT_RGB24,
110         },
111         {
112                 .pixelformat = V4L2_PIX_FMT_YUYV,
113         },
114         {
115                 .pixelformat = V4L2_PIX_FMT_UYVY,
116         },
117 };
118
119 #define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
120
121 /*
122  * Try format
123  */
124 static int omap_vout_try_format(struct v4l2_pix_format *pix)
125 {
126         int ifmt, bpp = 0;
127
128         pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT,
129                                                 (u32)VID_MAX_HEIGHT);
130         pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH);
131
132         for (ifmt = 0; ifmt < NUM_OUTPUT_FORMATS; ifmt++) {
133                 if (pix->pixelformat == omap_formats[ifmt].pixelformat)
134                         break;
135         }
136
137         if (ifmt == NUM_OUTPUT_FORMATS)
138                 ifmt = 0;
139
140         pix->pixelformat = omap_formats[ifmt].pixelformat;
141         pix->field = V4L2_FIELD_NONE;
142
143         switch (pix->pixelformat) {
144         case V4L2_PIX_FMT_YUYV:
145         case V4L2_PIX_FMT_UYVY:
146         default:
147                 pix->colorspace = V4L2_COLORSPACE_SRGB;
148                 bpp = YUYV_BPP;
149                 break;
150         case V4L2_PIX_FMT_RGB565:
151         case V4L2_PIX_FMT_RGB565X:
152                 pix->colorspace = V4L2_COLORSPACE_SRGB;
153                 bpp = RGB565_BPP;
154                 break;
155         case V4L2_PIX_FMT_RGB24:
156                 pix->colorspace = V4L2_COLORSPACE_SRGB;
157                 bpp = RGB24_BPP;
158                 break;
159         case V4L2_PIX_FMT_RGB32:
160         case V4L2_PIX_FMT_BGR32:
161                 pix->colorspace = V4L2_COLORSPACE_SRGB;
162                 bpp = RGB32_BPP;
163                 break;
164         }
165         pix->bytesperline = pix->width * bpp;
166         pix->sizeimage = pix->bytesperline * pix->height;
167
168         return bpp;
169 }
170
171 /*
172  * Convert V4L2 rotation to DSS rotation
173  *      V4L2 understand 0, 90, 180, 270.
174  *      Convert to 0, 1, 2 and 3 respectively for DSS
175  */
176 static int v4l2_rot_to_dss_rot(int v4l2_rotation,
177                         enum dss_rotation *rotation, bool mirror)
178 {
179         int ret = 0;
180
181         switch (v4l2_rotation) {
182         case 90:
183                 *rotation = dss_rotation_90_degree;
184                 break;
185         case 180:
186                 *rotation = dss_rotation_180_degree;
187                 break;
188         case 270:
189                 *rotation = dss_rotation_270_degree;
190                 break;
191         case 0:
192                 *rotation = dss_rotation_0_degree;
193                 break;
194         default:
195                 ret = -EINVAL;
196         }
197         return ret;
198 }
199
200 static int omap_vout_calculate_offset(struct omap_vout_device *vout)
201 {
202         struct omapvideo_info *ovid;
203         struct v4l2_rect *crop = &vout->crop;
204         struct v4l2_pix_format *pix = &vout->pix;
205         int *cropped_offset = &vout->cropped_offset;
206         int ps = 2, line_length = 0;
207
208         ovid = &vout->vid_info;
209
210         if (ovid->rotation_type == VOUT_ROT_VRFB) {
211                 omap_vout_calculate_vrfb_offset(vout);
212         } else {
213                 vout->line_length = line_length = pix->width;
214
215                 if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
216                         V4L2_PIX_FMT_UYVY == pix->pixelformat)
217                         ps = 2;
218                 else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat)
219                         ps = 4;
220                 else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat)
221                         ps = 3;
222
223                 vout->ps = ps;
224
225                 *cropped_offset = (line_length * ps) *
226                         crop->top + crop->left * ps;
227         }
228
229         v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n",
230                         __func__, vout->cropped_offset);
231
232         return 0;
233 }
234
235 /*
236  * Convert V4L2 pixel format to DSS pixel format
237  */
238 static int video_mode_to_dss_mode(struct omap_vout_device *vout)
239 {
240         struct omap_overlay *ovl;
241         struct omapvideo_info *ovid;
242         struct v4l2_pix_format *pix = &vout->pix;
243         enum omap_color_mode mode;
244
245         ovid = &vout->vid_info;
246         ovl = ovid->overlays[0];
247
248         switch (pix->pixelformat) {
249         case V4L2_PIX_FMT_YUYV:
250                 mode = OMAP_DSS_COLOR_YUV2;
251                 break;
252         case V4L2_PIX_FMT_UYVY:
253                 mode = OMAP_DSS_COLOR_UYVY;
254                 break;
255         case V4L2_PIX_FMT_RGB565:
256                 mode = OMAP_DSS_COLOR_RGB16;
257                 break;
258         case V4L2_PIX_FMT_RGB24:
259                 mode = OMAP_DSS_COLOR_RGB24P;
260                 break;
261         case V4L2_PIX_FMT_RGB32:
262                 mode = (ovl->id == OMAP_DSS_VIDEO1) ?
263                         OMAP_DSS_COLOR_RGB24U : OMAP_DSS_COLOR_ARGB32;
264                 break;
265         case V4L2_PIX_FMT_BGR32:
266                 mode = OMAP_DSS_COLOR_RGBX32;
267                 break;
268         default:
269                 mode = -EINVAL;
270                 break;
271         }
272         return mode;
273 }
274
275 /*
276  * Setup the overlay
277  */
278 static int omapvid_setup_overlay(struct omap_vout_device *vout,
279                 struct omap_overlay *ovl, int posx, int posy, int outw,
280                 int outh, u32 addr)
281 {
282         int ret = 0;
283         struct omap_overlay_info info;
284         int cropheight, cropwidth, pixwidth;
285
286         if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 &&
287                         (outw != vout->pix.width || outh != vout->pix.height)) {
288                 ret = -EINVAL;
289                 goto setup_ovl_err;
290         }
291
292         vout->dss_mode = video_mode_to_dss_mode(vout);
293         if (vout->dss_mode == -EINVAL) {
294                 ret = -EINVAL;
295                 goto setup_ovl_err;
296         }
297
298         /* Setup the input plane parameters according to
299          * rotation value selected.
300          */
301         if (is_rotation_90_or_270(vout)) {
302                 cropheight = vout->crop.width;
303                 cropwidth = vout->crop.height;
304                 pixwidth = vout->pix.height;
305         } else {
306                 cropheight = vout->crop.height;
307                 cropwidth = vout->crop.width;
308                 pixwidth = vout->pix.width;
309         }
310
311         ovl->get_overlay_info(ovl, &info);
312         info.paddr = addr;
313         info.width = cropwidth;
314         info.height = cropheight;
315         info.color_mode = vout->dss_mode;
316         info.mirror = vout->mirror;
317         info.pos_x = posx;
318         info.pos_y = posy;
319         info.out_width = outw;
320         info.out_height = outh;
321         info.global_alpha = vout->win.global_alpha;
322         if (!is_rotation_enabled(vout)) {
323                 info.rotation = 0;
324                 info.rotation_type = OMAP_DSS_ROT_DMA;
325                 info.screen_width = pixwidth;
326         } else {
327                 info.rotation = vout->rotation;
328                 info.rotation_type = OMAP_DSS_ROT_VRFB;
329                 info.screen_width = 2048;
330         }
331
332         v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
333                 "%s enable=%d addr=%pad width=%d\n height=%d color_mode=%d\n"
334                 "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
335                 "out_height=%d rotation_type=%d screen_width=%d\n", __func__,
336                 ovl->is_enabled(ovl), &info.paddr, info.width, info.height,
337                 info.color_mode, info.rotation, info.mirror, info.pos_x,
338                 info.pos_y, info.out_width, info.out_height, info.rotation_type,
339                 info.screen_width);
340
341         ret = ovl->set_overlay_info(ovl, &info);
342         if (ret)
343                 goto setup_ovl_err;
344
345         return 0;
346
347 setup_ovl_err:
348         v4l2_warn(&vout->vid_dev->v4l2_dev, "setup_overlay failed\n");
349         return ret;
350 }
351
352 /*
353  * Initialize the overlay structure
354  */
355 static int omapvid_init(struct omap_vout_device *vout, u32 addr)
356 {
357         int ret = 0, i;
358         struct v4l2_window *win;
359         struct omap_overlay *ovl;
360         int posx, posy, outw, outh;
361         struct omap_video_timings *timing;
362         struct omapvideo_info *ovid = &vout->vid_info;
363
364         win = &vout->win;
365         for (i = 0; i < ovid->num_overlays; i++) {
366                 struct omap_dss_device *dssdev;
367
368                 ovl = ovid->overlays[i];
369                 dssdev = ovl->get_device(ovl);
370
371                 if (!dssdev)
372                         return -EINVAL;
373
374                 timing = &dssdev->panel.timings;
375
376                 outw = win->w.width;
377                 outh = win->w.height;
378                 switch (vout->rotation) {
379                 case dss_rotation_90_degree:
380                         /* Invert the height and width for 90
381                          * and 270 degree rotation
382                          */
383                         swap(outw, outh);
384                         posy = (timing->y_res - win->w.width) - win->w.left;
385                         posx = win->w.top;
386                         break;
387
388                 case dss_rotation_180_degree:
389                         posx = (timing->x_res - win->w.width) - win->w.left;
390                         posy = (timing->y_res - win->w.height) - win->w.top;
391                         break;
392
393                 case dss_rotation_270_degree:
394                         swap(outw, outh);
395                         posy = win->w.left;
396                         posx = (timing->x_res - win->w.height) - win->w.top;
397                         break;
398
399                 default:
400                         posx = win->w.left;
401                         posy = win->w.top;
402                         break;
403                 }
404
405                 ret = omapvid_setup_overlay(vout, ovl, posx, posy,
406                                 outw, outh, addr);
407                 if (ret)
408                         goto omapvid_init_err;
409         }
410         return 0;
411
412 omapvid_init_err:
413         v4l2_warn(&vout->vid_dev->v4l2_dev, "apply_changes failed\n");
414         return ret;
415 }
416
417 /*
418  * Apply the changes set the go bit of DSS
419  */
420 static int omapvid_apply_changes(struct omap_vout_device *vout)
421 {
422         int i;
423         struct omap_overlay *ovl;
424         struct omapvideo_info *ovid = &vout->vid_info;
425
426         for (i = 0; i < ovid->num_overlays; i++) {
427                 struct omap_dss_device *dssdev;
428
429                 ovl = ovid->overlays[i];
430                 dssdev = ovl->get_device(ovl);
431                 if (!dssdev)
432                         return -EINVAL;
433                 ovl->manager->apply(ovl->manager);
434         }
435
436         return 0;
437 }
438
439 static int omapvid_handle_interlace_display(struct omap_vout_device *vout,
440                 unsigned int irqstatus, u64 ts)
441 {
442         u32 fid;
443
444         if (vout->first_int) {
445                 vout->first_int = 0;
446                 goto err;
447         }
448
449         if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
450                 fid = 1;
451         else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
452                 fid = 0;
453         else
454                 goto err;
455
456         vout->field_id ^= 1;
457         if (fid != vout->field_id) {
458                 if (fid == 0)
459                         vout->field_id = fid;
460         } else if (0 == fid) {
461                 if (vout->cur_frm == vout->next_frm)
462                         goto err;
463
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);
467                 vout->cur_frm = vout->next_frm;
468         } else {
469                 if (list_empty(&vout->dma_queue) ||
470                                 (vout->cur_frm != vout->next_frm))
471                         goto err;
472         }
473
474         return vout->field_id;
475 err:
476         return 0;
477 }
478
479 static void omap_vout_isr(void *arg, unsigned int irqstatus)
480 {
481         int ret, fid, mgr_id;
482         u32 addr, irq;
483         struct omap_overlay *ovl;
484         u64 ts;
485         struct omapvideo_info *ovid;
486         struct omap_dss_device *cur_display;
487         struct omap_vout_device *vout = (struct omap_vout_device *)arg;
488
489         ovid = &vout->vid_info;
490         ovl = ovid->overlays[0];
491
492         mgr_id = ovl->manager->id;
493
494         /* get the display device attached to the overlay */
495         cur_display = ovl->get_device(ovl);
496
497         if (!cur_display)
498                 return;
499
500         spin_lock(&vout->vbq_lock);
501         ts = ktime_get_ns();
502
503         switch (cur_display->type) {
504         case OMAP_DISPLAY_TYPE_DSI:
505         case OMAP_DISPLAY_TYPE_DPI:
506         case OMAP_DISPLAY_TYPE_DVI:
507                 if (mgr_id == OMAP_DSS_CHANNEL_LCD)
508                         irq = DISPC_IRQ_VSYNC;
509                 else if (mgr_id == OMAP_DSS_CHANNEL_LCD2)
510                         irq = DISPC_IRQ_VSYNC2;
511                 else
512                         goto vout_isr_err;
513
514                 if (!(irqstatus & irq))
515                         goto vout_isr_err;
516                 break;
517         case OMAP_DISPLAY_TYPE_VENC:
518                 fid = omapvid_handle_interlace_display(vout, irqstatus,
519                                 ts);
520                 if (!fid)
521                         goto vout_isr_err;
522                 break;
523         case OMAP_DISPLAY_TYPE_HDMI:
524                 if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
525                         goto vout_isr_err;
526                 break;
527         default:
528                 goto vout_isr_err;
529         }
530
531         if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
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);
535                 vout->cur_frm = vout->next_frm;
536         }
537
538         vout->first_int = 0;
539         if (list_empty(&vout->dma_queue))
540                 goto vout_isr_err;
541
542         vout->next_frm = list_entry(vout->dma_queue.next,
543                         struct omap_vout_buffer, queue);
544         list_del(&vout->next_frm->queue);
545
546         addr = (unsigned long)vout->queued_buf_addr[vout->next_frm->vbuf.vb2_buf.index]
547                 + vout->cropped_offset;
548
549         /* First save the configuration in ovelray structure */
550         ret = omapvid_init(vout, addr);
551         if (ret) {
552                 printk(KERN_ERR VOUT_NAME
553                         "failed to set overlay info\n");
554                 goto vout_isr_err;
555         }
556
557         /* Enable the pipeline and set the Go bit */
558         ret = omapvid_apply_changes(vout);
559         if (ret)
560                 printk(KERN_ERR VOUT_NAME "failed to change mode\n");
561
562 vout_isr_err:
563         spin_unlock(&vout->vbq_lock);
564 }
565
566
567 /*
568  * V4L2 ioctls
569  */
570 static int vidioc_querycap(struct file *file, void *fh,
571                 struct v4l2_capability *cap)
572 {
573         struct omap_vout_device *vout = video_drvdata(file);
574
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);
579         return 0;
580 }
581
582 static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
583                         struct v4l2_fmtdesc *fmt)
584 {
585         int index = fmt->index;
586
587         if (index >= NUM_OUTPUT_FORMATS)
588                 return -EINVAL;
589
590         fmt->flags = omap_formats[index].flags;
591         fmt->pixelformat = omap_formats[index].pixelformat;
592
593         return 0;
594 }
595
596 static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
597                         struct v4l2_format *f)
598 {
599         struct omap_vout_device *vout = video_drvdata(file);
600
601         f->fmt.pix = vout->pix;
602         return 0;
603
604 }
605
606 static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
607                         struct v4l2_format *f)
608 {
609         struct omap_overlay *ovl;
610         struct omapvideo_info *ovid;
611         struct omap_video_timings *timing;
612         struct omap_vout_device *vout = video_drvdata(file);
613         struct omap_dss_device *dssdev;
614
615         ovid = &vout->vid_info;
616         ovl = ovid->overlays[0];
617         /* get the display device attached to the overlay */
618         dssdev = ovl->get_device(ovl);
619
620         if (!dssdev)
621                 return -EINVAL;
622
623         timing = &dssdev->panel.timings;
624
625         vout->fbuf.fmt.height = timing->y_res;
626         vout->fbuf.fmt.width = timing->x_res;
627
628         omap_vout_try_format(&f->fmt.pix);
629         return 0;
630 }
631
632 static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
633                         struct v4l2_format *f)
634 {
635         int ret, bpp;
636         struct omap_overlay *ovl;
637         struct omapvideo_info *ovid;
638         struct omap_video_timings *timing;
639         struct omap_vout_device *vout = video_drvdata(file);
640         struct omap_dss_device *dssdev;
641
642         if (vb2_is_busy(&vout->vq))
643                 return -EBUSY;
644
645         ovid = &vout->vid_info;
646         ovl = ovid->overlays[0];
647         dssdev = ovl->get_device(ovl);
648
649         /* get the display device attached to the overlay */
650         if (!dssdev) {
651                 ret = -EINVAL;
652                 goto s_fmt_vid_out_exit;
653         }
654         timing = &dssdev->panel.timings;
655
656         /* We don't support RGB24-packed mode if vrfb rotation
657          * is enabled*/
658         if ((is_rotation_enabled(vout)) &&
659                         f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
660                 ret = -EINVAL;
661                 goto s_fmt_vid_out_exit;
662         }
663
664         /* get the framebuffer parameters */
665
666         if (is_rotation_90_or_270(vout)) {
667                 vout->fbuf.fmt.height = timing->x_res;
668                 vout->fbuf.fmt.width = timing->y_res;
669         } else {
670                 vout->fbuf.fmt.height = timing->y_res;
671                 vout->fbuf.fmt.width = timing->x_res;
672         }
673
674         /* change to smaller size is OK */
675
676         bpp = omap_vout_try_format(&f->fmt.pix);
677         f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp;
678
679         /* try & set the new output format */
680         vout->bpp = bpp;
681         vout->pix = f->fmt.pix;
682         vout->vrfb_bpp = 1;
683
684         /* If YUYV then vrfb bpp is 2, for  others its 1 */
685         if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat ||
686                         V4L2_PIX_FMT_UYVY == vout->pix.pixelformat)
687                 vout->vrfb_bpp = 2;
688
689         /* set default crop and win */
690         omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win);
691
692         ret = 0;
693
694 s_fmt_vid_out_exit:
695         return ret;
696 }
697
698 static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh,
699                         struct v4l2_format *f)
700 {
701         int ret = 0;
702         struct omap_vout_device *vout = video_drvdata(file);
703         struct omap_overlay *ovl;
704         struct omapvideo_info *ovid;
705         struct v4l2_window *win = &f->fmt.win;
706
707         ovid = &vout->vid_info;
708         ovl = ovid->overlays[0];
709
710         ret = omap_vout_try_window(&vout->fbuf, win);
711
712         if (!ret && !(ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA))
713                 win->global_alpha = 0;
714
715         return ret;
716 }
717
718 static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh,
719                         struct v4l2_format *f)
720 {
721         int ret = 0;
722         struct omap_overlay *ovl;
723         struct omapvideo_info *ovid;
724         struct omap_vout_device *vout = video_drvdata(file);
725         struct v4l2_window *win = &f->fmt.win;
726
727         ovid = &vout->vid_info;
728         ovl = ovid->overlays[0];
729
730         ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
731         if (!ret) {
732                 enum omap_dss_trans_key_type key_type =
733                         OMAP_DSS_COLOR_KEY_GFX_DST;
734                 int enable;
735
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                 }
761         }
762         return ret;
763 }
764
765 static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
766                         struct v4l2_format *f)
767 {
768         struct omap_overlay *ovl;
769         struct omapvideo_info *ovid;
770         struct omap_vout_device *vout = video_drvdata(file);
771         struct v4l2_window *win = &f->fmt.win;
772
773         ovid = &vout->vid_info;
774         ovl = ovid->overlays[0];
775
776         win->w = vout->win.w;
777         win->field = vout->win.field;
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;
786         return 0;
787 }
788
789 static int vidioc_g_selection(struct file *file, void *fh, struct v4l2_selection *sel)
790 {
791         struct omap_vout_device *vout = video_drvdata(file);
792         struct v4l2_pix_format *pix = &vout->pix;
793
794         if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
795                 return -EINVAL;
796
797         switch (sel->target) {
798         case V4L2_SEL_TGT_CROP:
799                 sel->r = vout->crop;
800                 break;
801         case V4L2_SEL_TGT_CROP_DEFAULT:
802                 omap_vout_default_crop(&vout->pix, &vout->fbuf, &sel->r);
803                 break;
804         case V4L2_SEL_TGT_CROP_BOUNDS:
805                 /* Width and height are always even */
806                 sel->r.width = pix->width & ~1;
807                 sel->r.height = pix->height & ~1;
808                 break;
809         default:
810                 return -EINVAL;
811         }
812         return 0;
813 }
814
815 static int vidioc_s_selection(struct file *file, void *fh, struct v4l2_selection *sel)
816 {
817         int ret = -EINVAL;
818         struct omap_vout_device *vout = video_drvdata(file);
819         struct omapvideo_info *ovid;
820         struct omap_overlay *ovl;
821         struct omap_video_timings *timing;
822         struct omap_dss_device *dssdev;
823
824         if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
825                 return -EINVAL;
826
827         if (sel->target != V4L2_SEL_TGT_CROP)
828                 return -EINVAL;
829
830         if (vb2_is_busy(&vout->vq))
831                 return -EBUSY;
832
833         ovid = &vout->vid_info;
834         ovl = ovid->overlays[0];
835         /* get the display device attached to the overlay */
836         dssdev = ovl->get_device(ovl);
837
838         if (!dssdev) {
839                 ret = -EINVAL;
840                 goto s_crop_err;
841         }
842
843         timing = &dssdev->panel.timings;
844
845         if (is_rotation_90_or_270(vout)) {
846                 vout->fbuf.fmt.height = timing->x_res;
847                 vout->fbuf.fmt.width = timing->y_res;
848         } else {
849                 vout->fbuf.fmt.height = timing->y_res;
850                 vout->fbuf.fmt.width = timing->x_res;
851         }
852
853         ret = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win,
854                                  &vout->fbuf, &sel->r);
855
856 s_crop_err:
857         return ret;
858 }
859
860 static int omap_vout_s_ctrl(struct v4l2_ctrl *ctrl)
861 {
862         struct omap_vout_device *vout =
863                 container_of(ctrl->handler, struct omap_vout_device, ctrl_handler);
864         int ret = 0;
865
866         switch (ctrl->id) {
867         case V4L2_CID_ROTATE: {
868                 struct omapvideo_info *ovid;
869                 int rotation = ctrl->val;
870
871                 ovid = &vout->vid_info;
872
873                 if (rotation && ovid->rotation_type == VOUT_ROT_NONE) {
874                         ret = -ERANGE;
875                         break;
876                 }
877
878                 if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
879                         ret = -EINVAL;
880                         break;
881                 }
882
883                 if (v4l2_rot_to_dss_rot(rotation, &vout->rotation,
884                                                         vout->mirror)) {
885                         ret = -EINVAL;
886                         break;
887                 }
888                 break;
889         }
890         case V4L2_CID_BG_COLOR:
891         {
892                 struct omap_overlay *ovl;
893                 unsigned int color = ctrl->val;
894                 struct omap_overlay_manager_info info;
895
896                 ovl = vout->vid_info.overlays[0];
897
898                 if (!ovl->manager || !ovl->manager->get_manager_info) {
899                         ret = -EINVAL;
900                         break;
901                 }
902
903                 ovl->manager->get_manager_info(ovl->manager, &info);
904                 info.default_color = color;
905                 if (ovl->manager->set_manager_info(ovl->manager, &info)) {
906                         ret = -EINVAL;
907                         break;
908                 }
909                 break;
910         }
911         case V4L2_CID_VFLIP:
912         {
913                 struct omapvideo_info *ovid;
914                 unsigned int mirror = ctrl->val;
915
916                 ovid = &vout->vid_info;
917
918                 if (mirror && ovid->rotation_type == VOUT_ROT_NONE) {
919                         ret = -ERANGE;
920                         break;
921                 }
922
923                 if (mirror  && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
924                         ret = -EINVAL;
925                         break;
926                 }
927                 vout->mirror = mirror;
928                 break;
929         }
930         default:
931                 return -EINVAL;
932         }
933         return ret;
934 }
935
936 static const struct v4l2_ctrl_ops omap_vout_ctrl_ops = {
937         .s_ctrl = omap_vout_s_ctrl,
938 };
939
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[])
944 {
945         struct omap_vout_device *vout = vb2_get_drv_priv(vq);
946         int size = vout->pix.sizeimage;
947
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)
951                         return -EINVAL;
952         }
953
954         if (*num_planes)
955                 return sizes[0] < size ? -EINVAL : 0;
956
957         *num_planes = 1;
958         sizes[0] = size;
959         return 0;
960 }
961
962 static int omap_vout_vb2_prepare(struct vb2_buffer *vb)
963 {
964         struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue);
965         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);
968
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;
974         }
975
976         vb2_set_plane_payload(vb, 0, vout->pix.sizeimage);
977         voutbuf->vbuf.field = V4L2_FIELD_NONE;
978
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;
1000
1001         /* Get the next frame from the buffer queue */
1002         vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next,
1003                         struct omap_vout_buffer, queue);
1004         /* Remove buffer from the buffer queue */
1005         list_del(&vout->cur_frm->queue);
1006         /* Initialize field_id and started member */
1007         vout->field_id = 0;
1008         vout->first_int = 1;
1009         vout->sequence = 0;
1010
1011         if (omap_vout_calculate_offset(vout)) {
1012                 ret = -EINVAL;
1013                 goto out;
1014         }
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]
1022                 + vout->cropped_offset;
1023
1024         mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1025                 | DISPC_IRQ_VSYNC2;
1026
1027         /* First save the configuration in overlay structure */
1028         ret = omapvid_init(vout, addr);
1029         if (ret) {
1030                 v4l2_err(&vout->vid_dev->v4l2_dev,
1031                                 "failed to set overlay info\n");
1032                 goto streamon_err1;
1033         }
1034
1035         omap_dispc_register_isr(omap_vout_isr, vout, mask);
1036
1037         /* Enable the pipeline and set the Go bit */
1038         ret = omapvid_apply_changes(vout);
1039         if (ret)
1040                 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1041
1042         for (j = 0; j < ovid->num_overlays; j++) {
1043                 struct omap_overlay *ovl = ovid->overlays[j];
1044                 struct omap_dss_device *dssdev = ovl->get_device(ovl);
1045
1046                 if (dssdev) {
1047                         ret = ovl->enable(ovl);
1048                         if (ret)
1049                                 goto streamon_err1;
1050                 }
1051         }
1052         return 0;
1053
1054 streamon_err1:
1055         mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1056                 | DISPC_IRQ_VSYNC2;
1057
1058         omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
1059
1060         for (j = 0; j < ovid->num_overlays; j++) {
1061                 struct omap_overlay *ovl = ovid->overlays[j];
1062                 struct omap_dss_device *dssdev = ovl->get_device(ovl);
1063
1064                 if (dssdev)
1065                         ovl->disable(ovl);
1066         }
1067         /* Turn of the pipeline */
1068         if (omapvid_apply_changes(vout))
1069                 v4l2_err(&vout->vid_dev->v4l2_dev,
1070                          "failed to change mode in streamoff\n");
1071
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         }
1078         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         }
1113 }
1114
1115 static int vidioc_s_fbuf(struct file *file, void *fh,
1116                                 const struct v4l2_framebuffer *a)
1117 {
1118         int enable = 0;
1119         struct omap_overlay *ovl;
1120         struct omapvideo_info *ovid;
1121         struct omap_vout_device *vout = video_drvdata(file);
1122         struct omap_overlay_manager_info info;
1123         enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
1124
1125         ovid = &vout->vid_info;
1126         ovl = ovid->overlays[0];
1127
1128         /* OMAP DSS doesn't support Source and Destination color
1129            key together */
1130         if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
1131                         (a->flags & V4L2_FBUF_FLAG_CHROMAKEY))
1132                 return -EINVAL;
1133         /* OMAP DSS Doesn't support the Destination color key
1134            and alpha blending together */
1135         if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
1136                         (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA))
1137                 return -EINVAL;
1138
1139         if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) {
1140                 vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1141                 key_type =  OMAP_DSS_COLOR_KEY_VID_SRC;
1142         } else
1143                 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1144
1145         if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) {
1146                 vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1147                 key_type =  OMAP_DSS_COLOR_KEY_GFX_DST;
1148         } else
1149                 vout->fbuf.flags &=  ~V4L2_FBUF_FLAG_CHROMAKEY;
1150
1151         if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY |
1152                                 V4L2_FBUF_FLAG_SRC_CHROMAKEY))
1153                 enable = 1;
1154         else
1155                 enable = 0;
1156         if (ovl->manager && ovl->manager->get_manager_info &&
1157                         ovl->manager->set_manager_info) {
1158
1159                 ovl->manager->get_manager_info(ovl->manager, &info);
1160                 info.trans_enabled = enable;
1161                 info.trans_key_type = key_type;
1162                 info.trans_key = vout->win.chromakey;
1163
1164                 if (ovl->manager->set_manager_info(ovl->manager, &info))
1165                         return -EINVAL;
1166         }
1167         if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) {
1168                 vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1169                 enable = 1;
1170         } else {
1171                 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
1172                 enable = 0;
1173         }
1174         if (ovl->manager && ovl->manager->get_manager_info &&
1175                         ovl->manager->set_manager_info) {
1176                 ovl->manager->get_manager_info(ovl->manager, &info);
1177                 /* enable this only if there is no zorder cap */
1178                 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
1179                         info.partial_alpha_enabled = enable;
1180                 if (ovl->manager->set_manager_info(ovl->manager, &info))
1181                         return -EINVAL;
1182         }
1183
1184         return 0;
1185 }
1186
1187 static int vidioc_g_fbuf(struct file *file, void *fh,
1188                 struct v4l2_framebuffer *a)
1189 {
1190         struct omap_overlay *ovl;
1191         struct omapvideo_info *ovid;
1192         struct omap_vout_device *vout = video_drvdata(file);
1193         struct omap_overlay_manager_info info;
1194         struct omap_video_timings *timing;
1195         struct omap_dss_device *dssdev;
1196
1197         ovid = &vout->vid_info;
1198         ovl = ovid->overlays[0];
1199         /* get the display device attached to the overlay */
1200         dssdev = ovl->get_device(ovl);
1201
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);
1222
1223         if (ovl->manager && ovl->manager->get_manager_info) {
1224                 ovl->manager->get_manager_info(ovl->manager, &info);
1225                 if (info.trans_key_type == OMAP_DSS_COLOR_KEY_VID_SRC)
1226                         a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1227                 if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
1228                         a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1229                 if (info.partial_alpha_enabled)
1230                         a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1231         }
1232
1233         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;
1255 }
1256
1257 static const struct v4l2_ioctl_ops vout_ioctl_ops = {
1258         .vidioc_querycap                        = vidioc_querycap,
1259         .vidioc_enum_fmt_vid_out                = vidioc_enum_fmt_vid_out,
1260         .vidioc_g_fmt_vid_out                   = vidioc_g_fmt_vid_out,
1261         .vidioc_try_fmt_vid_out                 = vidioc_try_fmt_vid_out,
1262         .vidioc_s_fmt_vid_out                   = vidioc_s_fmt_vid_out,
1263         .vidioc_s_fbuf                          = vidioc_s_fbuf,
1264         .vidioc_g_fbuf                          = vidioc_g_fbuf,
1265         .vidioc_try_fmt_vid_out_overlay         = vidioc_try_fmt_vid_overlay,
1266         .vidioc_s_fmt_vid_out_overlay           = vidioc_s_fmt_vid_overlay,
1267         .vidioc_g_fmt_vid_out_overlay           = vidioc_g_fmt_vid_overlay,
1268         .vidioc_g_selection                     = vidioc_g_selection,
1269         .vidioc_s_selection                     = vidioc_s_selection,
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,
1283 };
1284
1285 static const struct v4l2_file_operations omap_vout_fops = {
1286         .owner          = THIS_MODULE,
1287         .unlocked_ioctl = video_ioctl2,
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,
1302 };
1303
1304 /* Init functions used during driver initialization */
1305 /* Initial setup of video_data */
1306 static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
1307 {
1308         struct video_device *vfd;
1309         struct v4l2_pix_format *pix;
1310         struct omap_overlay *ovl = vout->vid_info.overlays[0];
1311         struct omap_dss_device *display = ovl->get_device(ovl);
1312         struct v4l2_ctrl_handler *hdl;
1313         struct vb2_queue *vq;
1314         int ret;
1315
1316         /* set the default pix */
1317         pix = &vout->pix;
1318
1319         /* Set the default picture of QVGA  */
1320         pix->width = QQVGA_WIDTH;
1321         pix->height = QQVGA_HEIGHT;
1322
1323         /* Default pixel format is RGB 5-6-5 */
1324         pix->pixelformat = V4L2_PIX_FMT_RGB565;
1325         pix->field = V4L2_FIELD_NONE;
1326         pix->bytesperline = pix->width * 2;
1327         pix->sizeimage = pix->bytesperline * pix->height;
1328         pix->colorspace = V4L2_COLORSPACE_SRGB;
1329
1330         vout->bpp = RGB565_BPP;
1331         vout->fbuf.fmt.width  =  display->panel.timings.x_res;
1332         vout->fbuf.fmt.height =  display->panel.timings.y_res;
1333         vout->cropped_offset = 0;
1334
1335         /* Set the data structures for the overlay parameters*/
1336         vout->fbuf.flags = V4L2_FBUF_FLAG_OVERLAY;
1337         vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
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;
1348
1349         omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
1350
1351         hdl = &vout->ctrl_handler;
1352         v4l2_ctrl_handler_init(hdl, 3);
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         }
1359         v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
1360                           V4L2_CID_BG_COLOR, 0, 0xffffff, 1, 0);
1361         if (hdl->error)
1362                 return hdl->error;
1363
1364         vout->rotation = 0;
1365         vout->mirror = false;
1366         INIT_LIST_HEAD(&vout->dma_queue);
1367         if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
1368                 vout->vrfb_bpp = 2;
1369
1370         /* initialize the video_device struct */
1371         vfd = vout->vfd = video_device_alloc();
1372
1373         if (!vfd) {
1374                 printk(KERN_ERR VOUT_NAME
1375                        ": could not allocate video device struct\n");
1376                 v4l2_ctrl_handler_free(hdl);
1377                 return -ENOMEM;
1378         }
1379         vfd->ctrl_handler = hdl;
1380         vfd->release = video_device_release;
1381         vfd->ioctl_ops = &vout_ioctl_ops;
1382
1383         strscpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
1384
1385         vfd->fops = &omap_vout_fops;
1386         vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
1387         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;
1391         mutex_init(&vout->lock);
1392
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;
1400
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;
1413 }
1414
1415 /* Setup video buffers */
1416 static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
1417                 int vid_num)
1418 {
1419         struct omapvideo_info *ovid;
1420         struct omap_vout_device *vout;
1421         struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1422         struct omap2video_device *vid_dev =
1423                 container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
1424         int ret = 0;
1425
1426         vout = vid_dev->vouts[vid_num];
1427         ovid = &vout->vid_info;
1428
1429         if (ovid->rotation_type == VOUT_ROT_VRFB) {
1430                 bool static_vrfb_allocation = (vid_num == 0) ?
1431                         vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
1432                 ret = omap_vout_setup_vrfb_bufs(pdev, vid_num,
1433                                 static_vrfb_allocation);
1434         }
1435         return ret;
1436 }
1437
1438 /* Create video out devices */
1439 static int __init omap_vout_create_video_devices(struct platform_device *pdev)
1440 {
1441         int ret = 0, k;
1442         struct omap_vout_device *vout;
1443         struct video_device *vfd = NULL;
1444         struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1445         struct omap2video_device *vid_dev = container_of(v4l2_dev,
1446                         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);
1451
1452         for (k = 0; k < pdev->num_resources; k++) {
1453
1454                 vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL);
1455                 if (!vout) {
1456                         dev_err(&pdev->dev, ": could not allocate memory\n");
1457                         return -ENOMEM;
1458                 }
1459
1460                 vout->vid = k;
1461                 vid_dev->vouts[k] = vout;
1462                 vout->vid_dev = vid_dev;
1463                 /* Select video2 if only 1 overlay is controlled by V4L2 */
1464                 if (pdev->num_resources == 1)
1465                         vout->vid_info.overlays[0] = vid_dev->overlays[k + 2];
1466                 else
1467                         /* Else select video1 and video2 one by one. */
1468                         vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
1469                 vout->vid_info.num_overlays = 1;
1470                 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;
1480
1481                 /* Set VRFB as rotation_type for omap2 and omap3 */
1482                 if (omap_vout_dss_omap24xx() || omap_vout_dss_omap34xx())
1483                         vout->vid_info.rotation_type = VOUT_ROT_VRFB;
1484
1485                 /* Setup the default configuration for the video devices
1486                  */
1487                 if (omap_vout_setup_video_data(vout) != 0) {
1488                         ret = -ENOMEM;
1489                         goto error;
1490                 }
1491
1492                 /* Allocate default number of buffers for the video streaming
1493                  * and reserve the VRFB space for rotation
1494                  */
1495                 if (omap_vout_setup_video_bufs(pdev, k) != 0) {
1496                         ret = -ENOMEM;
1497                         goto error1;
1498                 }
1499
1500                 /* Register the Video device with V4L2
1501                  */
1502                 vfd = vout->vfd;
1503                 if (video_register_device(vfd, VFL_TYPE_VIDEO, -1) < 0) {
1504                         dev_err(&pdev->dev,
1505                                 ": Could not register Video for Linux device\n");
1506                         vfd->minor = -1;
1507                         ret = -ENODEV;
1508                         goto error2;
1509                 }
1510                 video_set_drvdata(vfd, vout);
1511
1512                 dev_info(&pdev->dev,
1513                          ": registered and initialized video device %d\n",
1514                          vfd->minor);
1515                 if (k == (pdev->num_resources - 1))
1516                         return 0;
1517
1518                 continue;
1519 error2:
1520                 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
1521                         omap_vout_release_vrfb(vout);
1522 error1:
1523                 video_device_release(vfd);
1524 error:
1525                 kfree(vout);
1526                 return ret;
1527         }
1528
1529         return -ENODEV;
1530 }
1531 /* Driver functions */
1532 static void omap_vout_cleanup_device(struct omap_vout_device *vout)
1533 {
1534         struct video_device *vfd;
1535         struct omapvideo_info *ovid;
1536
1537         if (!vout)
1538                 return;
1539
1540         vfd = vout->vfd;
1541         ovid = &vout->vid_info;
1542         if (vfd) {
1543                 if (!video_is_registered(vfd)) {
1544                         /*
1545                          * The device was never registered, so release the
1546                          * video_device struct directly.
1547                          */
1548                         video_device_release(vfd);
1549                 } else {
1550                         /*
1551                          * The unregister function will release the video_device
1552                          * struct as well as unregistering it.
1553                          */
1554                         video_unregister_device(vfd);
1555                 }
1556         }
1557         v4l2_ctrl_handler_free(&vout->ctrl_handler);
1558         if (ovid->rotation_type == VOUT_ROT_VRFB) {
1559                 omap_vout_release_vrfb(vout);
1560                 /* Free the VRFB buffer if allocated
1561                  * init time
1562                  */
1563                 if (vout->vrfb_static_allocation)
1564                         omap_vout_free_vrfb_buffers(vout);
1565         }
1566
1567         kfree(vout);
1568 }
1569
1570 static int omap_vout_remove(struct platform_device *pdev)
1571 {
1572         int k;
1573         struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1574         struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
1575                         omap2video_device, v4l2_dev);
1576
1577         v4l2_device_unregister(v4l2_dev);
1578         for (k = 0; k < pdev->num_resources; k++)
1579                 omap_vout_cleanup_device(vid_dev->vouts[k]);
1580
1581         for (k = 0; k < vid_dev->num_displays; k++) {
1582                 if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED)
1583                         vid_dev->displays[k]->driver->disable(vid_dev->displays[k]);
1584
1585                 omap_dss_put_device(vid_dev->displays[k]);
1586         }
1587         kfree(vid_dev);
1588         return 0;
1589 }
1590
1591 static int __init omap_vout_probe(struct platform_device *pdev)
1592 {
1593         int ret = 0, i;
1594         struct omap_overlay *ovl;
1595         struct omap_dss_device *dssdev = NULL;
1596         struct omap_dss_device *def_display;
1597         struct omap2video_device *vid_dev = NULL;
1598
1599         if (omapdss_is_initialized() == false)
1600                 return -EPROBE_DEFER;
1601
1602         ret = omapdss_compat_init();
1603         if (ret) {
1604                 dev_err(&pdev->dev, "failed to init dss\n");
1605                 return ret;
1606         }
1607
1608         if (pdev->num_resources == 0) {
1609                 dev_err(&pdev->dev, "probed for an unknown device\n");
1610                 ret = -ENODEV;
1611                 goto err_dss_init;
1612         }
1613
1614         vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
1615         if (vid_dev == NULL) {
1616                 ret = -ENOMEM;
1617                 goto err_dss_init;
1618         }
1619
1620         vid_dev->num_displays = 0;
1621         for_each_dss_dev(dssdev) {
1622                 omap_dss_get_device(dssdev);
1623
1624                 if (!dssdev->driver) {
1625                         dev_warn(&pdev->dev, "no driver for display: %s\n",
1626                                         dssdev->name);
1627                         omap_dss_put_device(dssdev);
1628                         continue;
1629                 }
1630
1631                 vid_dev->displays[vid_dev->num_displays++] = dssdev;
1632         }
1633
1634         if (vid_dev->num_displays == 0) {
1635                 dev_err(&pdev->dev, "no displays\n");
1636                 ret = -EINVAL;
1637                 goto probe_err0;
1638         }
1639
1640         vid_dev->num_overlays = omap_dss_get_num_overlays();
1641         for (i = 0; i < vid_dev->num_overlays; i++)
1642                 vid_dev->overlays[i] = omap_dss_get_overlay(i);
1643
1644         vid_dev->num_managers = omap_dss_get_num_overlay_managers();
1645         for (i = 0; i < vid_dev->num_managers; i++)
1646                 vid_dev->managers[i] = omap_dss_get_overlay_manager(i);
1647
1648         /* Get the Video1 overlay and video2 overlay.
1649          * Setup the Display attached to that overlays
1650          */
1651         for (i = 1; i < vid_dev->num_overlays; i++) {
1652                 ovl = omap_dss_get_overlay(i);
1653                 dssdev = ovl->get_device(ovl);
1654
1655                 if (dssdev) {
1656                         def_display = dssdev;
1657                 } else {
1658                         dev_warn(&pdev->dev, "cannot find display\n");
1659                         def_display = NULL;
1660                 }
1661                 if (def_display) {
1662                         struct omap_dss_driver *dssdrv = def_display->driver;
1663
1664                         ret = dssdrv->enable(def_display);
1665                         if (ret) {
1666                                 /* Here we are not considering a error
1667                                  *  as display may be enabled by frame
1668                                  *  buffer driver
1669                                  */
1670                                 dev_warn(&pdev->dev,
1671                                         "'%s' Display already enabled\n",
1672                                         def_display->name);
1673                         }
1674                 }
1675         }
1676
1677         if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) {
1678                 dev_err(&pdev->dev, "v4l2_device_register failed\n");
1679                 ret = -ENODEV;
1680                 goto probe_err1;
1681         }
1682
1683         ret = omap_vout_create_video_devices(pdev);
1684         if (ret)
1685                 goto probe_err2;
1686
1687         for (i = 0; i < vid_dev->num_displays; i++) {
1688                 struct omap_dss_device *display = vid_dev->displays[i];
1689
1690                 if (display->driver->update)
1691                         display->driver->update(display, 0, 0,
1692                                         display->panel.timings.x_res,
1693                                         display->panel.timings.y_res);
1694         }
1695         return 0;
1696
1697 probe_err2:
1698         v4l2_device_unregister(&vid_dev->v4l2_dev);
1699 probe_err1:
1700         for (i = 1; i < vid_dev->num_overlays; i++) {
1701                 def_display = NULL;
1702                 ovl = omap_dss_get_overlay(i);
1703                 dssdev = ovl->get_device(ovl);
1704
1705                 if (dssdev)
1706                         def_display = dssdev;
1707
1708                 if (def_display && def_display->driver)
1709                         def_display->driver->disable(def_display);
1710         }
1711 probe_err0:
1712         kfree(vid_dev);
1713 err_dss_init:
1714         omapdss_compat_uninit();
1715         return ret;
1716 }
1717
1718 static struct platform_driver omap_vout_driver = {
1719         .driver = {
1720                 .name = VOUT_NAME,
1721         },
1722         .remove = omap_vout_remove,
1723 };
1724
1725 static int __init omap_vout_init(void)
1726 {
1727         if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) {
1728                 printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
1729                 return -EINVAL;
1730         }
1731         return 0;
1732 }
1733
1734 static void omap_vout_cleanup(void)
1735 {
1736         platform_driver_unregister(&omap_vout_driver);
1737 }
1738
1739 late_initcall(omap_vout_init);
1740 module_exit(omap_vout_cleanup);