4 * Copyright (C) 2005-2010 Texas Instruments.
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.
10 * Leveraged code from the OMAP2 camera driver
11 * Video-for-Linux (Version 2) camera capture driver for
12 * the OMAP24xx camera controller.
14 * Author: Andy Lowe (source@mvista.com)
16 * Copyright (C) 2004 MontaVista Software, Inc.
17 * Copyright (C) 2010 Texas Instruments.
20 * 20-APR-2006 Khasim Modified VRFB based Rotation,
21 * The image data is always read from 0 degree
23 * to the virtual space of desired rotation angle
24 * 4-DEC-2006 Jian Changed to support better memory management
26 * 17-Nov-2008 Hardik Changed driver to use video_ioctl2
28 * 23-Feb-2010 Vaibhav H Modified to use new DSS2 interface
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/dma-mapping.h>
39 #include <linux/irq.h>
40 #include <linux/videodev2.h>
41 #include <linux/slab.h>
43 #include <media/videobuf-dma-contig.h>
44 #include <media/v4l2-device.h>
45 #include <media/v4l2-ioctl.h>
48 #include <plat/vram.h>
49 #include <plat/vrfb.h>
50 #include <plat/display.h>
52 #include "omap_voutlib.h"
53 #include "omap_voutdef.h"
55 MODULE_AUTHOR("Texas Instruments");
56 MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
57 MODULE_LICENSE("GPL");
60 /* Driver Configuration macros */
61 #define VOUT_NAME "omap_vout"
63 enum omap_vout_channels
{
68 enum dma_channel_state
{
73 #define QQVGA_WIDTH 160
74 #define QQVGA_HEIGHT 120
76 /* Max Resolution supported by the driver */
77 #define VID_MAX_WIDTH 1280 /* Largest width */
78 #define VID_MAX_HEIGHT 720 /* Largest height */
80 /* Mimimum requirement is 2x2 for DSS */
81 #define VID_MIN_WIDTH 2
82 #define VID_MIN_HEIGHT 2
84 /* 2048 x 2048 is max res supported by OMAP display controller */
85 #define MAX_PIXELS_PER_LINE 2048
87 #define VRFB_TX_TIMEOUT 1000
88 #define VRFB_NUM_BUFS 4
90 /* Max buffer size tobe allocated during init */
91 #define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4)
93 static struct videobuf_queue_ops video_vbq_ops
;
94 /* Variables configurable through module params*/
95 static u32 video1_numbuffers
= 3;
96 static u32 video2_numbuffers
= 3;
97 static u32 video1_bufsize
= OMAP_VOUT_MAX_BUF_SIZE
;
98 static u32 video2_bufsize
= OMAP_VOUT_MAX_BUF_SIZE
;
99 static u32 vid1_static_vrfb_alloc
;
100 static u32 vid2_static_vrfb_alloc
;
103 /* Module parameters */
104 module_param(video1_numbuffers
, uint
, S_IRUGO
);
105 MODULE_PARM_DESC(video1_numbuffers
,
106 "Number of buffers to be allocated at init time for Video1 device.");
108 module_param(video2_numbuffers
, uint
, S_IRUGO
);
109 MODULE_PARM_DESC(video2_numbuffers
,
110 "Number of buffers to be allocated at init time for Video2 device.");
112 module_param(video1_bufsize
, uint
, S_IRUGO
);
113 MODULE_PARM_DESC(video1_bufsize
,
114 "Size of the buffer to be allocated for video1 device");
116 module_param(video2_bufsize
, uint
, S_IRUGO
);
117 MODULE_PARM_DESC(video2_bufsize
,
118 "Size of the buffer to be allocated for video2 device");
120 module_param(vid1_static_vrfb_alloc
, bool, S_IRUGO
);
121 MODULE_PARM_DESC(vid1_static_vrfb_alloc
,
122 "Static allocation of the VRFB buffer for video1 device");
124 module_param(vid2_static_vrfb_alloc
, bool, S_IRUGO
);
125 MODULE_PARM_DESC(vid2_static_vrfb_alloc
,
126 "Static allocation of the VRFB buffer for video2 device");
128 module_param(debug
, bool, S_IRUGO
);
129 MODULE_PARM_DESC(debug
, "Debug level (0-1)");
131 /* list of image formats supported by OMAP2 video pipelines */
132 const static struct v4l2_fmtdesc omap_formats
[] = {
134 /* Note: V4L2 defines RGB565 as:
137 * g2 g1 g0 r4 r3 r2 r1 r0 b4 b3 b2 b1 b0 g5 g4 g3
139 * We interpret RGB565 as:
142 * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3
144 .description
= "RGB565, le",
145 .pixelformat
= V4L2_PIX_FMT_RGB565
,
148 /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use
149 * this for RGB24 unpack mode, the last 8 bits are ignored
151 .description
= "RGB32, le",
152 .pixelformat
= V4L2_PIX_FMT_RGB32
,
155 /* Note: V4L2 defines RGB24 as: RGB-8-8-8 we use
156 * this for RGB24 packed mode
159 .description
= "RGB24, le",
160 .pixelformat
= V4L2_PIX_FMT_RGB24
,
163 .description
= "YUYV (YUV 4:2:2), packed",
164 .pixelformat
= V4L2_PIX_FMT_YUYV
,
167 .description
= "UYVY, packed",
168 .pixelformat
= V4L2_PIX_FMT_UYVY
,
172 #define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
177 static unsigned long omap_vout_alloc_buffer(u32 buf_size
, u32
*phys_addr
)
180 unsigned long virt_addr
, addr
;
182 size
= PAGE_ALIGN(buf_size
);
183 order
= get_order(size
);
184 virt_addr
= __get_free_pages(GFP_KERNEL
| GFP_DMA
, order
);
189 SetPageReserved(virt_to_page(addr
));
194 *phys_addr
= (u32
) virt_to_phys((void *) virt_addr
);
201 static void omap_vout_free_buffer(unsigned long virtaddr
, u32 buf_size
)
204 unsigned long addr
= virtaddr
;
206 size
= PAGE_ALIGN(buf_size
);
207 order
= get_order(size
);
210 ClearPageReserved(virt_to_page(addr
));
214 free_pages((unsigned long) virtaddr
, order
);
218 * Function for allocating video buffers
220 static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device
*vout
,
221 unsigned int *count
, int startindex
)
225 for (i
= 0; i
< *count
; i
++) {
226 if (!vout
->smsshado_virt_addr
[i
]) {
227 vout
->smsshado_virt_addr
[i
] =
228 omap_vout_alloc_buffer(vout
->smsshado_size
,
229 &vout
->smsshado_phy_addr
[i
]);
231 if (!vout
->smsshado_virt_addr
[i
] && startindex
!= -1) {
232 if (V4L2_MEMORY_MMAP
== vout
->memory
&& i
>= startindex
)
235 if (!vout
->smsshado_virt_addr
[i
]) {
236 for (j
= 0; j
< i
; j
++) {
237 omap_vout_free_buffer(
238 vout
->smsshado_virt_addr
[j
],
239 vout
->smsshado_size
);
240 vout
->smsshado_virt_addr
[j
] = 0;
241 vout
->smsshado_phy_addr
[j
] = 0;
246 memset((void *) vout
->smsshado_virt_addr
[i
], 0,
247 vout
->smsshado_size
);
255 static int omap_vout_try_format(struct v4l2_pix_format
*pix
)
259 pix
->height
= clamp(pix
->height
, (u32
)VID_MIN_HEIGHT
,
260 (u32
)VID_MAX_HEIGHT
);
261 pix
->width
= clamp(pix
->width
, (u32
)VID_MIN_WIDTH
, (u32
)VID_MAX_WIDTH
);
263 for (ifmt
= 0; ifmt
< NUM_OUTPUT_FORMATS
; ifmt
++) {
264 if (pix
->pixelformat
== omap_formats
[ifmt
].pixelformat
)
268 if (ifmt
== NUM_OUTPUT_FORMATS
)
271 pix
->pixelformat
= omap_formats
[ifmt
].pixelformat
;
272 pix
->field
= V4L2_FIELD_ANY
;
275 switch (pix
->pixelformat
) {
276 case V4L2_PIX_FMT_YUYV
:
277 case V4L2_PIX_FMT_UYVY
:
279 pix
->colorspace
= V4L2_COLORSPACE_JPEG
;
282 case V4L2_PIX_FMT_RGB565
:
283 case V4L2_PIX_FMT_RGB565X
:
284 pix
->colorspace
= V4L2_COLORSPACE_SRGB
;
287 case V4L2_PIX_FMT_RGB24
:
288 pix
->colorspace
= V4L2_COLORSPACE_SRGB
;
291 case V4L2_PIX_FMT_RGB32
:
292 case V4L2_PIX_FMT_BGR32
:
293 pix
->colorspace
= V4L2_COLORSPACE_SRGB
;
297 pix
->bytesperline
= pix
->width
* bpp
;
298 pix
->sizeimage
= pix
->bytesperline
* pix
->height
;
304 * omap_vout_uservirt_to_phys: This inline function is used to convert user
305 * space virtual address to physical address.
307 static u32
omap_vout_uservirt_to_phys(u32 virtp
)
309 unsigned long physp
= 0;
310 struct vm_area_struct
*vma
;
311 struct mm_struct
*mm
= current
->mm
;
313 vma
= find_vma(mm
, virtp
);
314 /* For kernel direct-mapped memory, take the easy way */
315 if (virtp
>= PAGE_OFFSET
) {
316 physp
= virt_to_phys((void *) virtp
);
317 } else if (vma
&& (vma
->vm_flags
& VM_IO
) && vma
->vm_pgoff
) {
318 /* this will catch, kernel-allocated, mmaped-to-usermode
320 physp
= (vma
->vm_pgoff
<< PAGE_SHIFT
) + (virtp
- vma
->vm_start
);
322 /* otherwise, use get_user_pages() for general userland pages */
323 int res
, nr_pages
= 1;
325 down_read(¤t
->mm
->mmap_sem
);
327 res
= get_user_pages(current
, current
->mm
, virtp
, nr_pages
, 1,
329 up_read(¤t
->mm
->mmap_sem
);
331 if (res
== nr_pages
) {
332 physp
= __pa(page_address(&pages
[0]) +
333 (virtp
& ~PAGE_MASK
));
335 printk(KERN_WARNING VOUT_NAME
336 "get_user_pages failed\n");
345 * Wakes up the application once the DMA transfer to VRFB space is completed.
347 static void omap_vout_vrfb_dma_tx_callback(int lch
, u16 ch_status
, void *data
)
349 struct vid_vrfb_dma
*t
= (struct vid_vrfb_dma
*) data
;
352 wake_up_interruptible(&t
->wait
);
356 * Release the VRFB context once the module exits
358 static void omap_vout_release_vrfb(struct omap_vout_device
*vout
)
362 for (i
= 0; i
< VRFB_NUM_BUFS
; i
++)
363 omap_vrfb_release_ctx(&vout
->vrfb_context
[i
]);
365 if (vout
->vrfb_dma_tx
.req_status
== DMA_CHAN_ALLOTED
) {
366 vout
->vrfb_dma_tx
.req_status
= DMA_CHAN_NOT_ALLOTED
;
367 omap_free_dma(vout
->vrfb_dma_tx
.dma_ch
);
372 * Return true if rotation is 90 or 270
374 static inline int rotate_90_or_270(const struct omap_vout_device
*vout
)
376 return (vout
->rotation
== dss_rotation_90_degree
||
377 vout
->rotation
== dss_rotation_270_degree
);
381 * Return true if rotation is enabled
383 static inline int rotation_enabled(const struct omap_vout_device
*vout
)
385 return vout
->rotation
|| vout
->mirror
;
389 * Reverse the rotation degree if mirroring is enabled
391 static inline int calc_rotation(const struct omap_vout_device
*vout
)
394 return vout
->rotation
;
396 switch (vout
->rotation
) {
397 case dss_rotation_90_degree
:
398 return dss_rotation_270_degree
;
399 case dss_rotation_270_degree
:
400 return dss_rotation_90_degree
;
401 case dss_rotation_180_degree
:
402 return dss_rotation_0_degree
;
404 return dss_rotation_180_degree
;
409 * Free the V4L2 buffers
411 static void omap_vout_free_buffers(struct omap_vout_device
*vout
)
415 /* Allocate memory for the buffers */
416 numbuffers
= (vout
->vid
) ? video2_numbuffers
: video1_numbuffers
;
417 vout
->buffer_size
= (vout
->vid
) ? video2_bufsize
: video1_bufsize
;
419 for (i
= 0; i
< numbuffers
; i
++) {
420 omap_vout_free_buffer(vout
->buf_virt_addr
[i
],
422 vout
->buf_phy_addr
[i
] = 0;
423 vout
->buf_virt_addr
[i
] = 0;
430 static void omap_vout_free_vrfb_buffers(struct omap_vout_device
*vout
)
434 for (j
= 0; j
< VRFB_NUM_BUFS
; j
++) {
435 omap_vout_free_buffer(vout
->smsshado_virt_addr
[j
],
436 vout
->smsshado_size
);
437 vout
->smsshado_virt_addr
[j
] = 0;
438 vout
->smsshado_phy_addr
[j
] = 0;
443 * Allocate the buffers for the VRFB space. Data is copied from V4L2
444 * buffers to the VRFB buffers using the DMA engine.
446 static int omap_vout_vrfb_buffer_setup(struct omap_vout_device
*vout
,
447 unsigned int *count
, unsigned int startindex
)
452 /* Allocate the VRFB buffers only if the buffers are not
453 * allocated during init time.
455 if ((rotation_enabled(vout
)) && !vout
->vrfb_static_allocation
)
456 if (omap_vout_allocate_vrfb_buffers(vout
, count
, startindex
))
459 if (vout
->dss_mode
== OMAP_DSS_COLOR_YUV2
||
460 vout
->dss_mode
== OMAP_DSS_COLOR_UYVY
)
465 for (i
= 0; i
< *count
; i
++)
466 omap_vrfb_setup(&vout
->vrfb_context
[i
],
467 vout
->smsshado_phy_addr
[i
], vout
->pix
.width
,
468 vout
->pix
.height
, vout
->bpp
, yuv_mode
);
474 * Convert V4L2 rotation to DSS rotation
475 * V4L2 understand 0, 90, 180, 270.
476 * Convert to 0, 1, 2 and 3 respectively for DSS
478 static int v4l2_rot_to_dss_rot(int v4l2_rotation
,
479 enum dss_rotation
*rotation
, bool mirror
)
483 switch (v4l2_rotation
) {
485 *rotation
= dss_rotation_90_degree
;
488 *rotation
= dss_rotation_180_degree
;
491 *rotation
= dss_rotation_270_degree
;
494 *rotation
= dss_rotation_0_degree
;
503 * Calculate the buffer offsets from which the streaming should
504 * start. This offset calculation is mainly required because of
505 * the VRFB 32 pixels alignment with rotation.
507 static int omap_vout_calculate_offset(struct omap_vout_device
*vout
)
509 struct omap_overlay
*ovl
;
510 enum dss_rotation rotation
;
511 struct omapvideo_info
*ovid
;
512 bool mirroring
= vout
->mirror
;
513 struct omap_dss_device
*cur_display
;
514 struct v4l2_rect
*crop
= &vout
->crop
;
515 struct v4l2_pix_format
*pix
= &vout
->pix
;
516 int *cropped_offset
= &vout
->cropped_offset
;
517 int vr_ps
= 1, ps
= 2, temp_ps
= 2;
518 int offset
= 0, ctop
= 0, cleft
= 0, line_length
= 0;
520 ovid
= &vout
->vid_info
;
521 ovl
= ovid
->overlays
[0];
522 /* get the display device attached to the overlay */
523 if (!ovl
->manager
|| !ovl
->manager
->device
)
526 cur_display
= ovl
->manager
->device
;
527 rotation
= calc_rotation(vout
);
529 if (V4L2_PIX_FMT_YUYV
== pix
->pixelformat
||
530 V4L2_PIX_FMT_UYVY
== pix
->pixelformat
) {
531 if (rotation_enabled(vout
)) {
533 * ps - Actual pixel size for YUYV/UYVY for
534 * VRFB/Mirroring is 4 bytes
535 * vr_ps - Virtually pixel size for YUYV/UYVY is
541 ps
= 2; /* otherwise the pixel size is 2 byte */
543 } else if (V4L2_PIX_FMT_RGB32
== pix
->pixelformat
) {
545 } else if (V4L2_PIX_FMT_RGB24
== pix
->pixelformat
) {
551 if (rotation_enabled(vout
)) {
552 line_length
= MAX_PIXELS_PER_LINE
;
553 ctop
= (pix
->height
- crop
->height
) - crop
->top
;
554 cleft
= (pix
->width
- crop
->width
) - crop
->left
;
556 line_length
= pix
->width
;
558 vout
->line_length
= line_length
;
560 case dss_rotation_90_degree
:
561 offset
= vout
->vrfb_context
[0].yoffset
*
562 vout
->vrfb_context
[0].bytespp
;
563 temp_ps
= ps
/ vr_ps
;
564 if (mirroring
== 0) {
565 *cropped_offset
= offset
+ line_length
*
566 temp_ps
* cleft
+ crop
->top
* temp_ps
;
568 *cropped_offset
= offset
+ line_length
* temp_ps
*
569 cleft
+ crop
->top
* temp_ps
+ (line_length
*
570 ((crop
->width
/ (vr_ps
)) - 1) * ps
);
573 case dss_rotation_180_degree
:
574 offset
= ((MAX_PIXELS_PER_LINE
* vout
->vrfb_context
[0].yoffset
*
575 vout
->vrfb_context
[0].bytespp
) +
576 (vout
->vrfb_context
[0].xoffset
*
577 vout
->vrfb_context
[0].bytespp
));
578 if (mirroring
== 0) {
579 *cropped_offset
= offset
+ (line_length
* ps
* ctop
) +
580 (cleft
/ vr_ps
) * ps
;
583 *cropped_offset
= offset
+ (line_length
* ps
* ctop
) +
584 (cleft
/ vr_ps
) * ps
+ (line_length
*
585 (crop
->height
- 1) * ps
);
588 case dss_rotation_270_degree
:
589 offset
= MAX_PIXELS_PER_LINE
* vout
->vrfb_context
[0].xoffset
*
590 vout
->vrfb_context
[0].bytespp
;
591 temp_ps
= ps
/ vr_ps
;
592 if (mirroring
== 0) {
593 *cropped_offset
= offset
+ line_length
*
594 temp_ps
* crop
->left
+ ctop
* ps
;
596 *cropped_offset
= offset
+ line_length
*
597 temp_ps
* crop
->left
+ ctop
* ps
+
598 (line_length
* ((crop
->width
/ vr_ps
) - 1) *
602 case dss_rotation_0_degree
:
603 if (mirroring
== 0) {
604 *cropped_offset
= (line_length
* ps
) *
605 crop
->top
+ (crop
->left
/ vr_ps
) * ps
;
607 *cropped_offset
= (line_length
* ps
) *
608 crop
->top
+ (crop
->left
/ vr_ps
) * ps
+
609 (line_length
* (crop
->height
- 1) * ps
);
613 *cropped_offset
= (line_length
* ps
* crop
->top
) /
614 vr_ps
+ (crop
->left
* ps
) / vr_ps
+
615 ((crop
->width
/ vr_ps
) - 1) * ps
;
618 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
, "%s Offset:%x\n",
619 __func__
, *cropped_offset
);
624 * Convert V4L2 pixel format to DSS pixel format
626 static int video_mode_to_dss_mode(struct omap_vout_device
*vout
)
628 struct omap_overlay
*ovl
;
629 struct omapvideo_info
*ovid
;
630 struct v4l2_pix_format
*pix
= &vout
->pix
;
631 enum omap_color_mode mode
;
633 ovid
= &vout
->vid_info
;
634 ovl
= ovid
->overlays
[0];
636 switch (pix
->pixelformat
) {
639 case V4L2_PIX_FMT_YUYV
:
640 mode
= OMAP_DSS_COLOR_YUV2
;
642 case V4L2_PIX_FMT_UYVY
:
643 mode
= OMAP_DSS_COLOR_UYVY
;
645 case V4L2_PIX_FMT_RGB565
:
646 mode
= OMAP_DSS_COLOR_RGB16
;
648 case V4L2_PIX_FMT_RGB24
:
649 mode
= OMAP_DSS_COLOR_RGB24P
;
651 case V4L2_PIX_FMT_RGB32
:
652 mode
= (ovl
->id
== OMAP_DSS_VIDEO1
) ?
653 OMAP_DSS_COLOR_RGB24U
: OMAP_DSS_COLOR_ARGB32
;
655 case V4L2_PIX_FMT_BGR32
:
656 mode
= OMAP_DSS_COLOR_RGBX32
;
667 int omapvid_setup_overlay(struct omap_vout_device
*vout
,
668 struct omap_overlay
*ovl
, int posx
, int posy
, int outw
,
672 struct omap_overlay_info info
;
673 int cropheight
, cropwidth
, pixheight
, pixwidth
;
675 if ((ovl
->caps
& OMAP_DSS_OVL_CAP_SCALE
) == 0 &&
676 (outw
!= vout
->pix
.width
|| outh
!= vout
->pix
.height
)) {
681 vout
->dss_mode
= video_mode_to_dss_mode(vout
);
682 if (vout
->dss_mode
== -EINVAL
) {
687 /* Setup the input plane parameters according to
688 * rotation value selected.
690 if (rotate_90_or_270(vout
)) {
691 cropheight
= vout
->crop
.width
;
692 cropwidth
= vout
->crop
.height
;
693 pixheight
= vout
->pix
.width
;
694 pixwidth
= vout
->pix
.height
;
696 cropheight
= vout
->crop
.height
;
697 cropwidth
= vout
->crop
.width
;
698 pixheight
= vout
->pix
.height
;
699 pixwidth
= vout
->pix
.width
;
702 ovl
->get_overlay_info(ovl
, &info
);
705 info
.width
= cropwidth
;
706 info
.height
= cropheight
;
707 info
.color_mode
= vout
->dss_mode
;
708 info
.mirror
= vout
->mirror
;
711 info
.out_width
= outw
;
712 info
.out_height
= outh
;
713 info
.global_alpha
= vout
->win
.global_alpha
;
714 if (!rotation_enabled(vout
)) {
716 info
.rotation_type
= OMAP_DSS_ROT_DMA
;
717 info
.screen_width
= pixwidth
;
719 info
.rotation
= vout
->rotation
;
720 info
.rotation_type
= OMAP_DSS_ROT_VRFB
;
721 info
.screen_width
= 2048;
724 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
,
725 "%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
726 "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
727 "out_height=%d rotation_type=%d screen_width=%d\n",
728 __func__
, info
.enabled
, info
.paddr
, info
.width
, info
.height
,
729 info
.color_mode
, info
.rotation
, info
.mirror
, info
.pos_x
,
730 info
.pos_y
, info
.out_width
, info
.out_height
, info
.rotation_type
,
733 ret
= ovl
->set_overlay_info(ovl
, &info
);
740 v4l2_warn(&vout
->vid_dev
->v4l2_dev
, "setup_overlay failed\n");
745 * Initialize the overlay structure
747 int omapvid_init(struct omap_vout_device
*vout
, u32 addr
)
750 struct v4l2_window
*win
;
751 struct omap_overlay
*ovl
;
752 int posx
, posy
, outw
, outh
, temp
;
753 struct omap_video_timings
*timing
;
754 struct omapvideo_info
*ovid
= &vout
->vid_info
;
757 for (i
= 0; i
< ovid
->num_overlays
; i
++) {
758 ovl
= ovid
->overlays
[i
];
759 if (!ovl
->manager
|| !ovl
->manager
->device
)
762 timing
= &ovl
->manager
->device
->panel
.timings
;
765 outh
= win
->w
.height
;
766 switch (vout
->rotation
) {
767 case dss_rotation_90_degree
:
768 /* Invert the height and width for 90
769 * and 270 degree rotation
774 posy
= (timing
->y_res
- win
->w
.width
) - win
->w
.left
;
778 case dss_rotation_180_degree
:
779 posx
= (timing
->x_res
- win
->w
.width
) - win
->w
.left
;
780 posy
= (timing
->y_res
- win
->w
.height
) - win
->w
.top
;
783 case dss_rotation_270_degree
:
788 posx
= (timing
->x_res
- win
->w
.height
) - win
->w
.top
;
797 ret
= omapvid_setup_overlay(vout
, ovl
, posx
, posy
,
800 goto omapvid_init_err
;
805 v4l2_warn(&vout
->vid_dev
->v4l2_dev
, "apply_changes failed\n");
810 * Apply the changes set the go bit of DSS
812 int omapvid_apply_changes(struct omap_vout_device
*vout
)
815 struct omap_overlay
*ovl
;
816 struct omapvideo_info
*ovid
= &vout
->vid_info
;
818 for (i
= 0; i
< ovid
->num_overlays
; i
++) {
819 ovl
= ovid
->overlays
[i
];
820 if (!ovl
->manager
|| !ovl
->manager
->device
)
822 ovl
->manager
->apply(ovl
->manager
);
828 void omap_vout_isr(void *arg
, unsigned int irqstatus
)
832 struct omap_overlay
*ovl
;
833 struct timeval timevalue
;
834 struct omapvideo_info
*ovid
;
835 struct omap_dss_device
*cur_display
;
836 struct omap_vout_device
*vout
= (struct omap_vout_device
*)arg
;
838 if (!vout
->streaming
)
841 ovid
= &vout
->vid_info
;
842 ovl
= ovid
->overlays
[0];
843 /* get the display device attached to the overlay */
844 if (!ovl
->manager
|| !ovl
->manager
->device
)
847 cur_display
= ovl
->manager
->device
;
849 spin_lock(&vout
->vbq_lock
);
850 do_gettimeofday(&timevalue
);
851 if (cur_display
->type
== OMAP_DISPLAY_TYPE_DPI
) {
852 if (!(irqstatus
& DISPC_IRQ_VSYNC
))
855 if (!vout
->first_int
&& (vout
->cur_frm
!= vout
->next_frm
)) {
856 vout
->cur_frm
->ts
= timevalue
;
857 vout
->cur_frm
->state
= VIDEOBUF_DONE
;
858 wake_up_interruptible(&vout
->cur_frm
->done
);
859 vout
->cur_frm
= vout
->next_frm
;
862 if (list_empty(&vout
->dma_queue
))
865 vout
->next_frm
= list_entry(vout
->dma_queue
.next
,
866 struct videobuf_buffer
, queue
);
867 list_del(&vout
->next_frm
->queue
);
869 vout
->next_frm
->state
= VIDEOBUF_ACTIVE
;
871 addr
= (unsigned long) vout
->queued_buf_addr
[vout
->next_frm
->i
]
872 + vout
->cropped_offset
;
874 /* First save the configuration in ovelray structure */
875 ret
= omapvid_init(vout
, addr
);
877 printk(KERN_ERR VOUT_NAME
878 "failed to set overlay info\n");
879 /* Enable the pipeline and set the Go bit */
880 ret
= omapvid_apply_changes(vout
);
882 printk(KERN_ERR VOUT_NAME
"failed to change mode\n");
885 if (vout
->first_int
) {
889 if (irqstatus
& DISPC_IRQ_EVSYNC_ODD
)
891 else if (irqstatus
& DISPC_IRQ_EVSYNC_EVEN
)
897 if (fid
!= vout
->field_id
) {
899 vout
->field_id
= fid
;
904 if (vout
->cur_frm
== vout
->next_frm
)
907 vout
->cur_frm
->ts
= timevalue
;
908 vout
->cur_frm
->state
= VIDEOBUF_DONE
;
909 wake_up_interruptible(&vout
->cur_frm
->done
);
910 vout
->cur_frm
= vout
->next_frm
;
911 } else if (1 == fid
) {
912 if (list_empty(&vout
->dma_queue
) ||
913 (vout
->cur_frm
!= vout
->next_frm
))
916 vout
->next_frm
= list_entry(vout
->dma_queue
.next
,
917 struct videobuf_buffer
, queue
);
918 list_del(&vout
->next_frm
->queue
);
920 vout
->next_frm
->state
= VIDEOBUF_ACTIVE
;
921 addr
= (unsigned long)
922 vout
->queued_buf_addr
[vout
->next_frm
->i
] +
923 vout
->cropped_offset
;
924 /* First save the configuration in ovelray structure */
925 ret
= omapvid_init(vout
, addr
);
927 printk(KERN_ERR VOUT_NAME
928 "failed to set overlay info\n");
929 /* Enable the pipeline and set the Go bit */
930 ret
= omapvid_apply_changes(vout
);
932 printk(KERN_ERR VOUT_NAME
933 "failed to change mode\n");
939 spin_unlock(&vout
->vbq_lock
);
943 /* Video buffer call backs */
946 * Buffer setup function is called by videobuf layer when REQBUF ioctl is
947 * called. This is used to setup buffers and return size and count of
948 * buffers allocated. After the call to this buffer, videobuf layer will
949 * setup buffer queue depending on the size and count of buffers
951 static int omap_vout_buffer_setup(struct videobuf_queue
*q
, unsigned int *count
,
954 int startindex
= 0, i
, j
;
955 u32 phy_addr
= 0, virt_addr
= 0;
956 struct omap_vout_device
*vout
= q
->priv_data
;
961 if (V4L2_BUF_TYPE_VIDEO_OUTPUT
!= q
->type
)
964 startindex
= (vout
->vid
== OMAP_VIDEO1
) ?
965 video1_numbuffers
: video2_numbuffers
;
966 if (V4L2_MEMORY_MMAP
== vout
->memory
&& *count
< startindex
)
969 if ((rotation_enabled(vout
)) && *count
> VRFB_NUM_BUFS
)
970 *count
= VRFB_NUM_BUFS
;
972 /* If rotation is enabled, allocate memory for VRFB space also */
973 if (rotation_enabled(vout
))
974 if (omap_vout_vrfb_buffer_setup(vout
, count
, startindex
))
977 if (V4L2_MEMORY_MMAP
!= vout
->memory
)
980 /* Now allocated the V4L2 buffers */
981 *size
= PAGE_ALIGN(vout
->pix
.width
* vout
->pix
.height
* vout
->bpp
);
982 startindex
= (vout
->vid
== OMAP_VIDEO1
) ?
983 video1_numbuffers
: video2_numbuffers
;
985 for (i
= startindex
; i
< *count
; i
++) {
986 vout
->buffer_size
= *size
;
988 virt_addr
= omap_vout_alloc_buffer(vout
->buffer_size
,
991 if (!rotation_enabled(vout
))
993 /* Free the VRFB buffers if no space for V4L2 buffers */
994 for (j
= i
; j
< *count
; j
++) {
995 omap_vout_free_buffer(
996 vout
->smsshado_virt_addr
[j
],
997 vout
->smsshado_size
);
998 vout
->smsshado_virt_addr
[j
] = 0;
999 vout
->smsshado_phy_addr
[j
] = 0;
1002 vout
->buf_virt_addr
[i
] = virt_addr
;
1003 vout
->buf_phy_addr
[i
] = phy_addr
;
1005 *count
= vout
->buffer_allocated
= i
;
1011 * Free the V4L2 buffers additionally allocated than default
1012 * number of buffers and free all the VRFB buffers
1014 static void omap_vout_free_allbuffers(struct omap_vout_device
*vout
)
1016 int num_buffers
= 0, i
;
1018 num_buffers
= (vout
->vid
== OMAP_VIDEO1
) ?
1019 video1_numbuffers
: video2_numbuffers
;
1021 for (i
= num_buffers
; i
< vout
->buffer_allocated
; i
++) {
1022 if (vout
->buf_virt_addr
[i
])
1023 omap_vout_free_buffer(vout
->buf_virt_addr
[i
],
1026 vout
->buf_virt_addr
[i
] = 0;
1027 vout
->buf_phy_addr
[i
] = 0;
1029 /* Free the VRFB buffers only if they are allocated
1030 * during reqbufs. Don't free if init time allocated
1032 if (!vout
->vrfb_static_allocation
) {
1033 for (i
= 0; i
< VRFB_NUM_BUFS
; i
++) {
1034 if (vout
->smsshado_virt_addr
[i
]) {
1035 omap_vout_free_buffer(
1036 vout
->smsshado_virt_addr
[i
],
1037 vout
->smsshado_size
);
1038 vout
->smsshado_virt_addr
[i
] = 0;
1039 vout
->smsshado_phy_addr
[i
] = 0;
1043 vout
->buffer_allocated
= num_buffers
;
1047 * This function will be called when VIDIOC_QBUF ioctl is called.
1048 * It prepare buffers before give out for the display. This function
1049 * converts user space virtual address into physical address if userptr memory
1050 * exchange mechanism is used. If rotation is enabled, it copies entire
1051 * buffer into VRFB memory space before giving it to the DSS.
1053 static int omap_vout_buffer_prepare(struct videobuf_queue
*q
,
1054 struct videobuf_buffer
*vb
,
1055 enum v4l2_field field
)
1058 struct vid_vrfb_dma
*tx
;
1059 enum dss_rotation rotation
;
1060 struct omap_vout_device
*vout
= q
->priv_data
;
1061 u32 dest_frame_index
= 0, src_element_index
= 0;
1062 u32 dest_element_index
= 0, src_frame_index
= 0;
1063 u32 elem_count
= 0, frame_count
= 0, pixsize
= 2;
1065 if (VIDEOBUF_NEEDS_INIT
== vb
->state
) {
1066 vb
->width
= vout
->pix
.width
;
1067 vb
->height
= vout
->pix
.height
;
1068 vb
->size
= vb
->width
* vb
->height
* vout
->bpp
;
1071 vb
->state
= VIDEOBUF_PREPARED
;
1072 /* if user pointer memory mechanism is used, get the physical
1073 * address of the buffer
1075 if (V4L2_MEMORY_USERPTR
== vb
->memory
) {
1078 /* Physical address */
1079 vout
->queued_buf_addr
[vb
->i
] = (u8
*)
1080 omap_vout_uservirt_to_phys(vb
->baddr
);
1082 vout
->queued_buf_addr
[vb
->i
] = (u8
*)vout
->buf_phy_addr
[vb
->i
];
1085 if (!rotation_enabled(vout
))
1088 dmabuf
= vout
->buf_phy_addr
[vb
->i
];
1089 /* If rotation is enabled, copy input buffer into VRFB
1090 * memory space using DMA. We are copying input buffer
1091 * into VRFB memory space of desired angle and DSS will
1092 * read image VRFB memory for 0 degree angle
1094 pixsize
= vout
->bpp
* vout
->vrfb_bpp
;
1096 * DMA transfer in double index mode
1100 dest_frame_index
= ((MAX_PIXELS_PER_LINE
* pixsize
) -
1101 (vout
->pix
.width
* vout
->bpp
)) + 1;
1103 /* Source and destination parameters */
1104 src_element_index
= 0;
1105 src_frame_index
= 0;
1106 dest_element_index
= 1;
1107 /* Number of elements per frame */
1108 elem_count
= vout
->pix
.width
* vout
->bpp
;
1109 frame_count
= vout
->pix
.height
;
1110 tx
= &vout
->vrfb_dma_tx
;
1112 omap_set_dma_transfer_params(tx
->dma_ch
, OMAP_DMA_DATA_TYPE_S32
,
1113 (elem_count
/ 4), frame_count
, OMAP_DMA_SYNC_ELEMENT
,
1115 /* src_port required only for OMAP1 */
1116 omap_set_dma_src_params(tx
->dma_ch
, 0, OMAP_DMA_AMODE_POST_INC
,
1117 dmabuf
, src_element_index
, src_frame_index
);
1118 /*set dma source burst mode for VRFB */
1119 omap_set_dma_src_burst_mode(tx
->dma_ch
, OMAP_DMA_DATA_BURST_16
);
1120 rotation
= calc_rotation(vout
);
1122 /* dest_port required only for OMAP1 */
1123 omap_set_dma_dest_params(tx
->dma_ch
, 0, OMAP_DMA_AMODE_DOUBLE_IDX
,
1124 vout
->vrfb_context
[vb
->i
].paddr
[0], dest_element_index
,
1126 /*set dma dest burst mode for VRFB */
1127 omap_set_dma_dest_burst_mode(tx
->dma_ch
, OMAP_DMA_DATA_BURST_16
);
1128 omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE
, 0x20, 0);
1130 omap_start_dma(tx
->dma_ch
);
1131 interruptible_sleep_on_timeout(&tx
->wait
, VRFB_TX_TIMEOUT
);
1133 if (tx
->tx_status
== 0) {
1134 omap_stop_dma(tx
->dma_ch
);
1137 /* Store buffers physical address into an array. Addresses
1138 * from this array will be used to configure DSS */
1139 vout
->queued_buf_addr
[vb
->i
] = (u8
*)
1140 vout
->vrfb_context
[vb
->i
].paddr
[rotation
];
1145 * Buffer queue function will be called from the videobuf layer when _QBUF
1146 * ioctl is called. It is used to enqueue buffer, which is ready to be
1149 static void omap_vout_buffer_queue(struct videobuf_queue
*q
,
1150 struct videobuf_buffer
*vb
)
1152 struct omap_vout_device
*vout
= q
->priv_data
;
1154 /* Driver is also maintainig a queue. So enqueue buffer in the driver
1156 list_add_tail(&vb
->queue
, &vout
->dma_queue
);
1158 vb
->state
= VIDEOBUF_QUEUED
;
1162 * Buffer release function is called from videobuf layer to release buffer
1163 * which are already allocated
1165 static void omap_vout_buffer_release(struct videobuf_queue
*q
,
1166 struct videobuf_buffer
*vb
)
1168 struct omap_vout_device
*vout
= q
->priv_data
;
1170 vb
->state
= VIDEOBUF_NEEDS_INIT
;
1172 if (V4L2_MEMORY_MMAP
!= vout
->memory
)
1179 static void omap_vout_vm_open(struct vm_area_struct
*vma
)
1181 struct omap_vout_device
*vout
= vma
->vm_private_data
;
1183 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
,
1184 "vm_open [vma=%08lx-%08lx]\n", vma
->vm_start
, vma
->vm_end
);
1188 static void omap_vout_vm_close(struct vm_area_struct
*vma
)
1190 struct omap_vout_device
*vout
= vma
->vm_private_data
;
1192 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
,
1193 "vm_close [vma=%08lx-%08lx]\n", vma
->vm_start
, vma
->vm_end
);
1197 static struct vm_operations_struct omap_vout_vm_ops
= {
1198 .open
= omap_vout_vm_open
,
1199 .close
= omap_vout_vm_close
,
1202 static int omap_vout_mmap(struct file
*file
, struct vm_area_struct
*vma
)
1206 unsigned long start
= vma
->vm_start
;
1207 unsigned long size
= (vma
->vm_end
- vma
->vm_start
);
1208 struct omap_vout_device
*vout
= file
->private_data
;
1209 struct videobuf_queue
*q
= &vout
->vbq
;
1211 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
,
1212 " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__
,
1213 vma
->vm_pgoff
, vma
->vm_start
, vma
->vm_end
);
1215 /* look for the buffer to map */
1216 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++) {
1217 if (NULL
== q
->bufs
[i
])
1219 if (V4L2_MEMORY_MMAP
!= q
->bufs
[i
]->memory
)
1221 if (q
->bufs
[i
]->boff
== (vma
->vm_pgoff
<< PAGE_SHIFT
))
1225 if (VIDEO_MAX_FRAME
== i
) {
1226 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
,
1227 "offset invalid [offset=0x%lx]\n",
1228 (vma
->vm_pgoff
<< PAGE_SHIFT
));
1231 q
->bufs
[i
]->baddr
= vma
->vm_start
;
1233 vma
->vm_flags
|= VM_RESERVED
;
1234 vma
->vm_page_prot
= pgprot_writecombine(vma
->vm_page_prot
);
1235 vma
->vm_ops
= &omap_vout_vm_ops
;
1236 vma
->vm_private_data
= (void *) vout
;
1237 pos
= (void *)vout
->buf_virt_addr
[i
];
1238 vma
->vm_pgoff
= virt_to_phys((void *)pos
) >> PAGE_SHIFT
;
1241 pfn
= virt_to_phys((void *) pos
) >> PAGE_SHIFT
;
1242 if (remap_pfn_range(vma
, start
, pfn
, PAGE_SIZE
, PAGE_SHARED
))
1249 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
, "Exiting %s\n", __func__
);
1254 static int omap_vout_release(struct file
*file
)
1256 unsigned int ret
, i
;
1257 struct videobuf_queue
*q
;
1258 struct omapvideo_info
*ovid
;
1259 struct omap_vout_device
*vout
= file
->private_data
;
1261 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
, "Entering %s\n", __func__
);
1262 ovid
= &vout
->vid_info
;
1268 /* Disable all the overlay managers connected with this interface */
1269 for (i
= 0; i
< ovid
->num_overlays
; i
++) {
1270 struct omap_overlay
*ovl
= ovid
->overlays
[i
];
1271 if (ovl
->manager
&& ovl
->manager
->device
) {
1272 struct omap_overlay_info info
;
1273 ovl
->get_overlay_info(ovl
, &info
);
1275 ovl
->set_overlay_info(ovl
, &info
);
1278 /* Turn off the pipeline */
1279 ret
= omapvid_apply_changes(vout
);
1281 v4l2_warn(&vout
->vid_dev
->v4l2_dev
,
1282 "Unable to apply changes\n");
1284 /* Free all buffers */
1285 omap_vout_free_allbuffers(vout
);
1286 videobuf_mmap_free(q
);
1288 /* Even if apply changes fails we should continue
1289 freeing allocated memory */
1290 if (vout
->streaming
) {
1293 mask
= DISPC_IRQ_VSYNC
| DISPC_IRQ_EVSYNC_EVEN
|
1294 DISPC_IRQ_EVSYNC_ODD
;
1295 omap_dispc_unregister_isr(omap_vout_isr
, vout
, mask
);
1296 vout
->streaming
= 0;
1298 videobuf_streamoff(q
);
1299 videobuf_queue_cancel(q
);
1302 if (vout
->mmap_count
!= 0)
1303 vout
->mmap_count
= 0;
1306 file
->private_data
= NULL
;
1308 if (vout
->buffer_allocated
)
1309 videobuf_mmap_free(q
);
1311 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
, "Exiting %s\n", __func__
);
1315 static int omap_vout_open(struct file
*file
)
1317 struct videobuf_queue
*q
;
1318 struct omap_vout_device
*vout
= NULL
;
1320 vout
= video_drvdata(file
);
1321 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
, "Entering %s\n", __func__
);
1326 /* for now, we only support single open */
1332 file
->private_data
= vout
;
1333 vout
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT
;
1336 video_vbq_ops
.buf_setup
= omap_vout_buffer_setup
;
1337 video_vbq_ops
.buf_prepare
= omap_vout_buffer_prepare
;
1338 video_vbq_ops
.buf_release
= omap_vout_buffer_release
;
1339 video_vbq_ops
.buf_queue
= omap_vout_buffer_queue
;
1340 spin_lock_init(&vout
->vbq_lock
);
1342 videobuf_queue_dma_contig_init(q
, &video_vbq_ops
, q
->dev
,
1343 &vout
->vbq_lock
, vout
->type
, V4L2_FIELD_NONE
,
1344 sizeof(struct videobuf_buffer
), vout
, NULL
);
1346 v4l2_dbg(1, debug
, &vout
->vid_dev
->v4l2_dev
, "Exiting %s\n", __func__
);
1353 static int vidioc_querycap(struct file
*file
, void *fh
,
1354 struct v4l2_capability
*cap
)
1356 struct omap_vout_device
*vout
= fh
;
1358 strlcpy(cap
->driver
, VOUT_NAME
, sizeof(cap
->driver
));
1359 strlcpy(cap
->card
, vout
->vfd
->name
, sizeof(cap
->card
));
1360 cap
->bus_info
[0] = '\0';
1361 cap
->capabilities
= V4L2_CAP_STREAMING
| V4L2_CAP_VIDEO_OUTPUT
;
1366 static int vidioc_enum_fmt_vid_out(struct file
*file
, void *fh
,
1367 struct v4l2_fmtdesc
*fmt
)
1369 int index
= fmt
->index
;
1370 enum v4l2_buf_type type
= fmt
->type
;
1374 if (index
>= NUM_OUTPUT_FORMATS
)
1377 fmt
->flags
= omap_formats
[index
].flags
;
1378 strlcpy(fmt
->description
, omap_formats
[index
].description
,
1379 sizeof(fmt
->description
));
1380 fmt
->pixelformat
= omap_formats
[index
].pixelformat
;
1385 static int vidioc_g_fmt_vid_out(struct file
*file
, void *fh
,
1386 struct v4l2_format
*f
)
1388 struct omap_vout_device
*vout
= fh
;
1390 f
->fmt
.pix
= vout
->pix
;
1395 static int vidioc_try_fmt_vid_out(struct file
*file
, void *fh
,
1396 struct v4l2_format
*f
)
1398 struct omap_overlay
*ovl
;
1399 struct omapvideo_info
*ovid
;
1400 struct omap_video_timings
*timing
;
1401 struct omap_vout_device
*vout
= fh
;
1403 ovid
= &vout
->vid_info
;
1404 ovl
= ovid
->overlays
[0];
1406 if (!ovl
->manager
|| !ovl
->manager
->device
)
1408 /* get the display device attached to the overlay */
1409 timing
= &ovl
->manager
->device
->panel
.timings
;
1411 vout
->fbuf
.fmt
.height
= timing
->y_res
;
1412 vout
->fbuf
.fmt
.width
= timing
->x_res
;
1414 omap_vout_try_format(&f
->fmt
.pix
);
1418 static int vidioc_s_fmt_vid_out(struct file
*file
, void *fh
,
1419 struct v4l2_format
*f
)
1422 struct omap_overlay
*ovl
;
1423 struct omapvideo_info
*ovid
;
1424 struct omap_video_timings
*timing
;
1425 struct omap_vout_device
*vout
= fh
;
1427 if (vout
->streaming
)
1430 mutex_lock(&vout
->lock
);
1432 ovid
= &vout
->vid_info
;
1433 ovl
= ovid
->overlays
[0];
1435 /* get the display device attached to the overlay */
1436 if (!ovl
->manager
|| !ovl
->manager
->device
) {
1438 goto s_fmt_vid_out_exit
;
1440 timing
= &ovl
->manager
->device
->panel
.timings
;
1442 /* We dont support RGB24-packed mode if vrfb rotation
1444 if ((rotation_enabled(vout
)) &&
1445 f
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_RGB24
) {
1447 goto s_fmt_vid_out_exit
;
1450 /* get the framebuffer parameters */
1452 if (rotate_90_or_270(vout
)) {
1453 vout
->fbuf
.fmt
.height
= timing
->x_res
;
1454 vout
->fbuf
.fmt
.width
= timing
->y_res
;
1456 vout
->fbuf
.fmt
.height
= timing
->y_res
;
1457 vout
->fbuf
.fmt
.width
= timing
->x_res
;
1460 /* change to samller size is OK */
1462 bpp
= omap_vout_try_format(&f
->fmt
.pix
);
1463 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.width
* f
->fmt
.pix
.height
* bpp
;
1465 /* try & set the new output format */
1467 vout
->pix
= f
->fmt
.pix
;
1470 /* If YUYV then vrfb bpp is 2, for others its 1 */
1471 if (V4L2_PIX_FMT_YUYV
== vout
->pix
.pixelformat
||
1472 V4L2_PIX_FMT_UYVY
== vout
->pix
.pixelformat
)
1475 /* set default crop and win */
1476 omap_vout_new_format(&vout
->pix
, &vout
->fbuf
, &vout
->crop
, &vout
->win
);
1478 /* Save the changes in the overlay strcuture */
1479 ret
= omapvid_init(vout
, 0);
1481 v4l2_err(&vout
->vid_dev
->v4l2_dev
, "failed to change mode\n");
1482 goto s_fmt_vid_out_exit
;
1488 mutex_unlock(&vout
->lock
);
1492 static int vidioc_try_fmt_vid_overlay(struct file
*file
, void *fh
,
1493 struct v4l2_format
*f
)
1496 struct omap_vout_device
*vout
= fh
;
1497 struct v4l2_window
*win
= &f
->fmt
.win
;
1499 ret
= omap_vout_try_window(&vout
->fbuf
, win
);
1502 if (vout
->vid
== OMAP_VIDEO1
)
1503 win
->global_alpha
= 255;
1505 win
->global_alpha
= f
->fmt
.win
.global_alpha
;
1511 static int vidioc_s_fmt_vid_overlay(struct file
*file
, void *fh
,
1512 struct v4l2_format
*f
)
1515 struct omap_overlay
*ovl
;
1516 struct omapvideo_info
*ovid
;
1517 struct omap_vout_device
*vout
= fh
;
1518 struct v4l2_window
*win
= &f
->fmt
.win
;
1520 mutex_lock(&vout
->lock
);
1521 ovid
= &vout
->vid_info
;
1522 ovl
= ovid
->overlays
[0];
1524 ret
= omap_vout_new_window(&vout
->crop
, &vout
->win
, &vout
->fbuf
, win
);
1526 /* Video1 plane does not support global alpha */
1527 if (ovl
->id
== OMAP_DSS_VIDEO1
)
1528 vout
->win
.global_alpha
= 255;
1530 vout
->win
.global_alpha
= f
->fmt
.win
.global_alpha
;
1532 vout
->win
.chromakey
= f
->fmt
.win
.chromakey
;
1534 mutex_unlock(&vout
->lock
);
1538 static int vidioc_enum_fmt_vid_overlay(struct file
*file
, void *fh
,
1539 struct v4l2_fmtdesc
*fmt
)
1541 int index
= fmt
->index
;
1542 enum v4l2_buf_type type
= fmt
->type
;
1546 if (index
>= NUM_OUTPUT_FORMATS
)
1549 fmt
->flags
= omap_formats
[index
].flags
;
1550 strlcpy(fmt
->description
, omap_formats
[index
].description
,
1551 sizeof(fmt
->description
));
1552 fmt
->pixelformat
= omap_formats
[index
].pixelformat
;
1556 static int vidioc_g_fmt_vid_overlay(struct file
*file
, void *fh
,
1557 struct v4l2_format
*f
)
1560 struct omap_overlay
*ovl
;
1561 struct omapvideo_info
*ovid
;
1562 struct omap_vout_device
*vout
= fh
;
1563 struct omap_overlay_manager_info info
;
1564 struct v4l2_window
*win
= &f
->fmt
.win
;
1566 ovid
= &vout
->vid_info
;
1567 ovl
= ovid
->overlays
[0];
1569 win
->w
= vout
->win
.w
;
1570 win
->field
= vout
->win
.field
;
1571 win
->global_alpha
= vout
->win
.global_alpha
;
1573 if (ovl
->manager
&& ovl
->manager
->get_manager_info
) {
1574 ovl
->manager
->get_manager_info(ovl
->manager
, &info
);
1575 key_value
= info
.trans_key
;
1577 win
->chromakey
= key_value
;
1581 static int vidioc_cropcap(struct file
*file
, void *fh
,
1582 struct v4l2_cropcap
*cropcap
)
1584 struct omap_vout_device
*vout
= fh
;
1585 struct v4l2_pix_format
*pix
= &vout
->pix
;
1587 if (cropcap
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
1590 /* Width and height are always even */
1591 cropcap
->bounds
.width
= pix
->width
& ~1;
1592 cropcap
->bounds
.height
= pix
->height
& ~1;
1594 omap_vout_default_crop(&vout
->pix
, &vout
->fbuf
, &cropcap
->defrect
);
1595 cropcap
->pixelaspect
.numerator
= 1;
1596 cropcap
->pixelaspect
.denominator
= 1;
1600 static int vidioc_g_crop(struct file
*file
, void *fh
, struct v4l2_crop
*crop
)
1602 struct omap_vout_device
*vout
= fh
;
1604 if (crop
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
1606 crop
->c
= vout
->crop
;
1610 static int vidioc_s_crop(struct file
*file
, void *fh
, struct v4l2_crop
*crop
)
1613 struct omap_vout_device
*vout
= fh
;
1614 struct omapvideo_info
*ovid
;
1615 struct omap_overlay
*ovl
;
1616 struct omap_video_timings
*timing
;
1618 if (vout
->streaming
)
1621 mutex_lock(&vout
->lock
);
1622 ovid
= &vout
->vid_info
;
1623 ovl
= ovid
->overlays
[0];
1625 if (!ovl
->manager
|| !ovl
->manager
->device
) {
1629 /* get the display device attached to the overlay */
1630 timing
= &ovl
->manager
->device
->panel
.timings
;
1632 if (rotate_90_or_270(vout
)) {
1633 vout
->fbuf
.fmt
.height
= timing
->x_res
;
1634 vout
->fbuf
.fmt
.width
= timing
->y_res
;
1636 vout
->fbuf
.fmt
.height
= timing
->y_res
;
1637 vout
->fbuf
.fmt
.width
= timing
->x_res
;
1640 if (crop
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT
)
1641 ret
= omap_vout_new_crop(&vout
->pix
, &vout
->crop
, &vout
->win
,
1642 &vout
->fbuf
, &crop
->c
);
1645 mutex_unlock(&vout
->lock
);
1649 static int vidioc_queryctrl(struct file
*file
, void *fh
,
1650 struct v4l2_queryctrl
*ctrl
)
1655 case V4L2_CID_ROTATE
:
1656 ret
= v4l2_ctrl_query_fill(ctrl
, 0, 270, 90, 0);
1658 case V4L2_CID_BG_COLOR
:
1659 ret
= v4l2_ctrl_query_fill(ctrl
, 0, 0xFFFFFF, 1, 0);
1661 case V4L2_CID_VFLIP
:
1662 ret
= v4l2_ctrl_query_fill(ctrl
, 0, 1, 1, 0);
1665 ctrl
->name
[0] = '\0';
1671 static int vidioc_g_ctrl(struct file
*file
, void *fh
, struct v4l2_control
*ctrl
)
1674 struct omap_vout_device
*vout
= fh
;
1677 case V4L2_CID_ROTATE
:
1678 ctrl
->value
= vout
->control
[0].value
;
1680 case V4L2_CID_BG_COLOR
:
1682 struct omap_overlay_manager_info info
;
1683 struct omap_overlay
*ovl
;
1685 ovl
= vout
->vid_info
.overlays
[0];
1686 if (!ovl
->manager
|| !ovl
->manager
->get_manager_info
) {
1691 ovl
->manager
->get_manager_info(ovl
->manager
, &info
);
1692 ctrl
->value
= info
.default_color
;
1695 case V4L2_CID_VFLIP
:
1696 ctrl
->value
= vout
->control
[2].value
;
1704 static int vidioc_s_ctrl(struct file
*file
, void *fh
, struct v4l2_control
*a
)
1707 struct omap_vout_device
*vout
= fh
;
1710 case V4L2_CID_ROTATE
:
1712 int rotation
= a
->value
;
1714 mutex_lock(&vout
->lock
);
1716 if (rotation
&& vout
->pix
.pixelformat
== V4L2_PIX_FMT_RGB24
) {
1717 mutex_unlock(&vout
->lock
);
1722 if (v4l2_rot_to_dss_rot(rotation
, &vout
->rotation
,
1724 mutex_unlock(&vout
->lock
);
1729 vout
->control
[0].value
= rotation
;
1730 mutex_unlock(&vout
->lock
);
1733 case V4L2_CID_BG_COLOR
:
1735 struct omap_overlay
*ovl
;
1736 unsigned int color
= a
->value
;
1737 struct omap_overlay_manager_info info
;
1739 ovl
= vout
->vid_info
.overlays
[0];
1741 mutex_lock(&vout
->lock
);
1742 if (!ovl
->manager
|| !ovl
->manager
->get_manager_info
) {
1743 mutex_unlock(&vout
->lock
);
1748 ovl
->manager
->get_manager_info(ovl
->manager
, &info
);
1749 info
.default_color
= color
;
1750 if (ovl
->manager
->set_manager_info(ovl
->manager
, &info
)) {
1751 mutex_unlock(&vout
->lock
);
1756 vout
->control
[1].value
= color
;
1757 mutex_unlock(&vout
->lock
);
1760 case V4L2_CID_VFLIP
:
1762 struct omap_overlay
*ovl
;
1763 struct omapvideo_info
*ovid
;
1764 unsigned int mirror
= a
->value
;
1766 ovid
= &vout
->vid_info
;
1767 ovl
= ovid
->overlays
[0];
1769 mutex_lock(&vout
->lock
);
1771 if (mirror
&& vout
->pix
.pixelformat
== V4L2_PIX_FMT_RGB24
) {
1772 mutex_unlock(&vout
->lock
);
1776 vout
->mirror
= mirror
;
1777 vout
->control
[2].value
= mirror
;
1778 mutex_unlock(&vout
->lock
);
1787 static int vidioc_reqbufs(struct file
*file
, void *fh
,
1788 struct v4l2_requestbuffers
*req
)
1791 unsigned int i
, num_buffers
= 0;
1792 struct omap_vout_device
*vout
= fh
;
1793 struct videobuf_queue
*q
= &vout
->vbq
;
1795 if ((req
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
) || (req
->count
< 0))
1797 /* if memory is not mmp or userptr
1799 if ((V4L2_MEMORY_MMAP
!= req
->memory
) &&
1800 (V4L2_MEMORY_USERPTR
!= req
->memory
))
1803 mutex_lock(&vout
->lock
);
1804 /* Cannot be requested when streaming is on */
1805 if (vout
->streaming
) {
1810 /* If buffers are already allocated free them */
1811 if (q
->bufs
[0] && (V4L2_MEMORY_MMAP
== q
->bufs
[0]->memory
)) {
1812 if (vout
->mmap_count
) {
1816 num_buffers
= (vout
->vid
== OMAP_VIDEO1
) ?
1817 video1_numbuffers
: video2_numbuffers
;
1818 for (i
= num_buffers
; i
< vout
->buffer_allocated
; i
++) {
1819 omap_vout_free_buffer(vout
->buf_virt_addr
[i
],
1821 vout
->buf_virt_addr
[i
] = 0;
1822 vout
->buf_phy_addr
[i
] = 0;
1824 vout
->buffer_allocated
= num_buffers
;
1825 videobuf_mmap_free(q
);
1826 } else if (q
->bufs
[0] && (V4L2_MEMORY_USERPTR
== q
->bufs
[0]->memory
)) {
1827 if (vout
->buffer_allocated
) {
1828 videobuf_mmap_free(q
);
1829 for (i
= 0; i
< vout
->buffer_allocated
; i
++) {
1833 vout
->buffer_allocated
= 0;
1837 /*store the memory type in data structure */
1838 vout
->memory
= req
->memory
;
1840 INIT_LIST_HEAD(&vout
->dma_queue
);
1842 /* call videobuf_reqbufs api */
1843 ret
= videobuf_reqbufs(q
, req
);
1847 vout
->buffer_allocated
= req
->count
;
1850 mutex_unlock(&vout
->lock
);
1854 static int vidioc_querybuf(struct file
*file
, void *fh
,
1855 struct v4l2_buffer
*b
)
1857 struct omap_vout_device
*vout
= fh
;
1859 return videobuf_querybuf(&vout
->vbq
, b
);
1862 static int vidioc_qbuf(struct file
*file
, void *fh
,
1863 struct v4l2_buffer
*buffer
)
1865 struct omap_vout_device
*vout
= fh
;
1866 struct videobuf_queue
*q
= &vout
->vbq
;
1868 if ((V4L2_BUF_TYPE_VIDEO_OUTPUT
!= buffer
->type
) ||
1869 (buffer
->index
>= vout
->buffer_allocated
) ||
1870 (q
->bufs
[buffer
->index
]->memory
!= buffer
->memory
)) {
1873 if (V4L2_MEMORY_USERPTR
== buffer
->memory
) {
1874 if ((buffer
->length
< vout
->pix
.sizeimage
) ||
1875 (0 == buffer
->m
.userptr
)) {
1880 if ((rotation_enabled(vout
)) &&
1881 vout
->vrfb_dma_tx
.req_status
== DMA_CHAN_NOT_ALLOTED
) {
1882 v4l2_warn(&vout
->vid_dev
->v4l2_dev
,
1883 "DMA Channel not allocated for Rotation\n");
1887 return videobuf_qbuf(q
, buffer
);
1890 static int vidioc_dqbuf(struct file
*file
, void *fh
, struct v4l2_buffer
*b
)
1892 struct omap_vout_device
*vout
= fh
;
1893 struct videobuf_queue
*q
= &vout
->vbq
;
1895 if (!vout
->streaming
)
1898 if (file
->f_flags
& O_NONBLOCK
)
1899 /* Call videobuf_dqbuf for non blocking mode */
1900 return videobuf_dqbuf(q
, (struct v4l2_buffer
*)b
, 1);
1902 /* Call videobuf_dqbuf for blocking mode */
1903 return videobuf_dqbuf(q
, (struct v4l2_buffer
*)b
, 0);
1906 static int vidioc_streamon(struct file
*file
, void *fh
, enum v4l2_buf_type i
)
1909 u32 addr
= 0, mask
= 0;
1910 struct omap_vout_device
*vout
= fh
;
1911 struct videobuf_queue
*q
= &vout
->vbq
;
1912 struct omapvideo_info
*ovid
= &vout
->vid_info
;
1914 mutex_lock(&vout
->lock
);
1916 if (vout
->streaming
) {
1921 ret
= videobuf_streamon(q
);
1925 if (list_empty(&vout
->dma_queue
)) {
1930 /* Get the next frame from the buffer queue */
1931 vout
->next_frm
= vout
->cur_frm
= list_entry(vout
->dma_queue
.next
,
1932 struct videobuf_buffer
, queue
);
1933 /* Remove buffer from the buffer queue */
1934 list_del(&vout
->cur_frm
->queue
);
1935 /* Mark state of the current frame to active */
1936 vout
->cur_frm
->state
= VIDEOBUF_ACTIVE
;
1937 /* Initialize field_id and started member */
1940 /* set flag here. Next QBUF will start DMA */
1941 vout
->streaming
= 1;
1943 vout
->first_int
= 1;
1945 if (omap_vout_calculate_offset(vout
)) {
1949 addr
= (unsigned long) vout
->queued_buf_addr
[vout
->cur_frm
->i
]
1950 + vout
->cropped_offset
;
1952 mask
= DISPC_IRQ_VSYNC
| DISPC_IRQ_EVSYNC_EVEN
| DISPC_IRQ_EVSYNC_ODD
;
1954 omap_dispc_register_isr(omap_vout_isr
, vout
, mask
);
1956 for (j
= 0; j
< ovid
->num_overlays
; j
++) {
1957 struct omap_overlay
*ovl
= ovid
->overlays
[j
];
1959 if (ovl
->manager
&& ovl
->manager
->device
) {
1960 struct omap_overlay_info info
;
1961 ovl
->get_overlay_info(ovl
, &info
);
1964 if (ovl
->set_overlay_info(ovl
, &info
)) {
1971 /* First save the configuration in ovelray structure */
1972 ret
= omapvid_init(vout
, addr
);
1974 v4l2_err(&vout
->vid_dev
->v4l2_dev
,
1975 "failed to set overlay info\n");
1976 /* Enable the pipeline and set the Go bit */
1977 ret
= omapvid_apply_changes(vout
);
1979 v4l2_err(&vout
->vid_dev
->v4l2_dev
, "failed to change mode\n");
1985 ret
= videobuf_streamoff(q
);
1987 mutex_unlock(&vout
->lock
);
1991 static int vidioc_streamoff(struct file
*file
, void *fh
, enum v4l2_buf_type i
)
1995 struct omap_vout_device
*vout
= fh
;
1996 struct omapvideo_info
*ovid
= &vout
->vid_info
;
1998 if (!vout
->streaming
)
2001 vout
->streaming
= 0;
2002 mask
= DISPC_IRQ_VSYNC
| DISPC_IRQ_EVSYNC_EVEN
| DISPC_IRQ_EVSYNC_ODD
;
2004 omap_dispc_unregister_isr(omap_vout_isr
, vout
, mask
);
2006 for (j
= 0; j
< ovid
->num_overlays
; j
++) {
2007 struct omap_overlay
*ovl
= ovid
->overlays
[j
];
2009 if (ovl
->manager
&& ovl
->manager
->device
) {
2010 struct omap_overlay_info info
;
2012 ovl
->get_overlay_info(ovl
, &info
);
2014 ret
= ovl
->set_overlay_info(ovl
, &info
);
2016 v4l2_err(&vout
->vid_dev
->v4l2_dev
,
2017 "failed to update overlay info in streamoff\n");
2021 /* Turn of the pipeline */
2022 ret
= omapvid_apply_changes(vout
);
2024 v4l2_err(&vout
->vid_dev
->v4l2_dev
, "failed to change mode in"
2027 INIT_LIST_HEAD(&vout
->dma_queue
);
2028 ret
= videobuf_streamoff(&vout
->vbq
);
2033 static int vidioc_s_fbuf(struct file
*file
, void *fh
,
2034 struct v4l2_framebuffer
*a
)
2037 struct omap_overlay
*ovl
;
2038 struct omapvideo_info
*ovid
;
2039 struct omap_vout_device
*vout
= fh
;
2040 struct omap_overlay_manager_info info
;
2041 enum omap_dss_trans_key_type key_type
= OMAP_DSS_COLOR_KEY_GFX_DST
;
2043 ovid
= &vout
->vid_info
;
2044 ovl
= ovid
->overlays
[0];
2046 /* OMAP DSS doesn't support Source and Destination color
2048 if ((a
->flags
& V4L2_FBUF_FLAG_SRC_CHROMAKEY
) &&
2049 (a
->flags
& V4L2_FBUF_FLAG_CHROMAKEY
))
2051 /* OMAP DSS Doesn't support the Destination color key
2052 and alpha blending together */
2053 if ((a
->flags
& V4L2_FBUF_FLAG_CHROMAKEY
) &&
2054 (a
->flags
& V4L2_FBUF_FLAG_LOCAL_ALPHA
))
2057 if ((a
->flags
& V4L2_FBUF_FLAG_SRC_CHROMAKEY
)) {
2058 vout
->fbuf
.flags
|= V4L2_FBUF_FLAG_SRC_CHROMAKEY
;
2059 key_type
= OMAP_DSS_COLOR_KEY_VID_SRC
;
2061 vout
->fbuf
.flags
&= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY
;
2063 if ((a
->flags
& V4L2_FBUF_FLAG_CHROMAKEY
)) {
2064 vout
->fbuf
.flags
|= V4L2_FBUF_FLAG_CHROMAKEY
;
2065 key_type
= OMAP_DSS_COLOR_KEY_GFX_DST
;
2067 vout
->fbuf
.flags
&= ~V4L2_FBUF_FLAG_CHROMAKEY
;
2069 if (a
->flags
& (V4L2_FBUF_FLAG_CHROMAKEY
|
2070 V4L2_FBUF_FLAG_SRC_CHROMAKEY
))
2074 if (ovl
->manager
&& ovl
->manager
->get_manager_info
&&
2075 ovl
->manager
->set_manager_info
) {
2077 ovl
->manager
->get_manager_info(ovl
->manager
, &info
);
2078 info
.trans_enabled
= enable
;
2079 info
.trans_key_type
= key_type
;
2080 info
.trans_key
= vout
->win
.chromakey
;
2082 if (ovl
->manager
->set_manager_info(ovl
->manager
, &info
))
2085 if (a
->flags
& V4L2_FBUF_FLAG_LOCAL_ALPHA
) {
2086 vout
->fbuf
.flags
|= V4L2_FBUF_FLAG_LOCAL_ALPHA
;
2089 vout
->fbuf
.flags
&= ~V4L2_FBUF_FLAG_LOCAL_ALPHA
;
2092 if (ovl
->manager
&& ovl
->manager
->get_manager_info
&&
2093 ovl
->manager
->set_manager_info
) {
2094 ovl
->manager
->get_manager_info(ovl
->manager
, &info
);
2095 info
.alpha_enabled
= enable
;
2096 if (ovl
->manager
->set_manager_info(ovl
->manager
, &info
))
2103 static int vidioc_g_fbuf(struct file
*file
, void *fh
,
2104 struct v4l2_framebuffer
*a
)
2106 struct omap_overlay
*ovl
;
2107 struct omapvideo_info
*ovid
;
2108 struct omap_vout_device
*vout
= fh
;
2109 struct omap_overlay_manager_info info
;
2111 ovid
= &vout
->vid_info
;
2112 ovl
= ovid
->overlays
[0];
2115 a
->capability
= V4L2_FBUF_CAP_LOCAL_ALPHA
| V4L2_FBUF_CAP_CHROMAKEY
2116 | V4L2_FBUF_CAP_SRC_CHROMAKEY
;
2118 if (ovl
->manager
&& ovl
->manager
->get_manager_info
) {
2119 ovl
->manager
->get_manager_info(ovl
->manager
, &info
);
2120 if (info
.trans_key_type
== OMAP_DSS_COLOR_KEY_VID_SRC
)
2121 a
->flags
|= V4L2_FBUF_FLAG_SRC_CHROMAKEY
;
2122 if (info
.trans_key_type
== OMAP_DSS_COLOR_KEY_GFX_DST
)
2123 a
->flags
|= V4L2_FBUF_FLAG_CHROMAKEY
;
2125 if (ovl
->manager
&& ovl
->manager
->get_manager_info
) {
2126 ovl
->manager
->get_manager_info(ovl
->manager
, &info
);
2127 if (info
.alpha_enabled
)
2128 a
->flags
|= V4L2_FBUF_FLAG_LOCAL_ALPHA
;
2134 static const struct v4l2_ioctl_ops vout_ioctl_ops
= {
2135 .vidioc_querycap
= vidioc_querycap
,
2136 .vidioc_enum_fmt_vid_out
= vidioc_enum_fmt_vid_out
,
2137 .vidioc_g_fmt_vid_out
= vidioc_g_fmt_vid_out
,
2138 .vidioc_try_fmt_vid_out
= vidioc_try_fmt_vid_out
,
2139 .vidioc_s_fmt_vid_out
= vidioc_s_fmt_vid_out
,
2140 .vidioc_queryctrl
= vidioc_queryctrl
,
2141 .vidioc_g_ctrl
= vidioc_g_ctrl
,
2142 .vidioc_s_fbuf
= vidioc_s_fbuf
,
2143 .vidioc_g_fbuf
= vidioc_g_fbuf
,
2144 .vidioc_s_ctrl
= vidioc_s_ctrl
,
2145 .vidioc_try_fmt_vid_overlay
= vidioc_try_fmt_vid_overlay
,
2146 .vidioc_s_fmt_vid_overlay
= vidioc_s_fmt_vid_overlay
,
2147 .vidioc_enum_fmt_vid_overlay
= vidioc_enum_fmt_vid_overlay
,
2148 .vidioc_g_fmt_vid_overlay
= vidioc_g_fmt_vid_overlay
,
2149 .vidioc_cropcap
= vidioc_cropcap
,
2150 .vidioc_g_crop
= vidioc_g_crop
,
2151 .vidioc_s_crop
= vidioc_s_crop
,
2152 .vidioc_reqbufs
= vidioc_reqbufs
,
2153 .vidioc_querybuf
= vidioc_querybuf
,
2154 .vidioc_qbuf
= vidioc_qbuf
,
2155 .vidioc_dqbuf
= vidioc_dqbuf
,
2156 .vidioc_streamon
= vidioc_streamon
,
2157 .vidioc_streamoff
= vidioc_streamoff
,
2160 static const struct v4l2_file_operations omap_vout_fops
= {
2161 .owner
= THIS_MODULE
,
2162 .unlocked_ioctl
= video_ioctl2
,
2163 .mmap
= omap_vout_mmap
,
2164 .open
= omap_vout_open
,
2165 .release
= omap_vout_release
,
2168 /* Init functions used during driver initialization */
2169 /* Initial setup of video_data */
2170 static int __init
omap_vout_setup_video_data(struct omap_vout_device
*vout
)
2172 struct video_device
*vfd
;
2173 struct v4l2_pix_format
*pix
;
2174 struct v4l2_control
*control
;
2175 struct omap_dss_device
*display
=
2176 vout
->vid_info
.overlays
[0]->manager
->device
;
2178 /* set the default pix */
2181 /* Set the default picture of QVGA */
2182 pix
->width
= QQVGA_WIDTH
;
2183 pix
->height
= QQVGA_HEIGHT
;
2185 /* Default pixel format is RGB 5-6-5 */
2186 pix
->pixelformat
= V4L2_PIX_FMT_RGB565
;
2187 pix
->field
= V4L2_FIELD_ANY
;
2188 pix
->bytesperline
= pix
->width
* 2;
2189 pix
->sizeimage
= pix
->bytesperline
* pix
->height
;
2191 pix
->colorspace
= V4L2_COLORSPACE_JPEG
;
2193 vout
->bpp
= RGB565_BPP
;
2194 vout
->fbuf
.fmt
.width
= display
->panel
.timings
.x_res
;
2195 vout
->fbuf
.fmt
.height
= display
->panel
.timings
.y_res
;
2197 /* Set the data structures for the overlay parameters*/
2198 vout
->win
.global_alpha
= 255;
2199 vout
->fbuf
.flags
= 0;
2200 vout
->fbuf
.capability
= V4L2_FBUF_CAP_LOCAL_ALPHA
|
2201 V4L2_FBUF_CAP_SRC_CHROMAKEY
| V4L2_FBUF_CAP_CHROMAKEY
;
2202 vout
->win
.chromakey
= 0;
2204 omap_vout_new_format(pix
, &vout
->fbuf
, &vout
->crop
, &vout
->win
);
2206 /*Initialize the control variables for
2207 rotation, flipping and background color. */
2208 control
= vout
->control
;
2209 control
[0].id
= V4L2_CID_ROTATE
;
2210 control
[0].value
= 0;
2213 vout
->control
[2].id
= V4L2_CID_HFLIP
;
2214 vout
->control
[2].value
= 0;
2217 control
[1].id
= V4L2_CID_BG_COLOR
;
2218 control
[1].value
= 0;
2220 /* initialize the video_device struct */
2221 vfd
= vout
->vfd
= video_device_alloc();
2224 printk(KERN_ERR VOUT_NAME
": could not allocate"
2225 " video device struct\n");
2228 vfd
->release
= video_device_release
;
2229 vfd
->ioctl_ops
= &vout_ioctl_ops
;
2231 strlcpy(vfd
->name
, VOUT_NAME
, sizeof(vfd
->name
));
2233 vfd
->fops
= &omap_vout_fops
;
2234 vfd
->v4l2_dev
= &vout
->vid_dev
->v4l2_dev
;
2235 mutex_init(&vout
->lock
);
2242 /* Setup video buffers */
2243 static int __init
omap_vout_setup_video_bufs(struct platform_device
*pdev
,
2248 int image_width
, image_height
;
2249 struct video_device
*vfd
;
2250 struct omap_vout_device
*vout
;
2251 int static_vrfb_allocation
= 0, vrfb_num_bufs
= VRFB_NUM_BUFS
;
2252 struct v4l2_device
*v4l2_dev
= platform_get_drvdata(pdev
);
2253 struct omap2video_device
*vid_dev
=
2254 container_of(v4l2_dev
, struct omap2video_device
, v4l2_dev
);
2256 vout
= vid_dev
->vouts
[vid_num
];
2259 numbuffers
= (vid_num
== 0) ? video1_numbuffers
: video2_numbuffers
;
2260 vout
->buffer_size
= (vid_num
== 0) ? video1_bufsize
: video2_bufsize
;
2261 dev_info(&pdev
->dev
, "Buffer Size = %d\n", vout
->buffer_size
);
2263 for (i
= 0; i
< numbuffers
; i
++) {
2264 vout
->buf_virt_addr
[i
] =
2265 omap_vout_alloc_buffer(vout
->buffer_size
,
2266 (u32
*) &vout
->buf_phy_addr
[i
]);
2267 if (!vout
->buf_virt_addr
[i
]) {
2274 for (i
= 0; i
< VRFB_NUM_BUFS
; i
++) {
2275 if (omap_vrfb_request_ctx(&vout
->vrfb_context
[i
])) {
2276 dev_info(&pdev
->dev
, ": VRFB allocation failed\n");
2277 for (j
= 0; j
< i
; j
++)
2278 omap_vrfb_release_ctx(&vout
->vrfb_context
[j
]);
2283 vout
->cropped_offset
= 0;
2285 /* Calculate VRFB memory size */
2286 /* allocate for worst case size */
2287 image_width
= VID_MAX_WIDTH
/ TILE_SIZE
;
2288 if (VID_MAX_WIDTH
% TILE_SIZE
)
2291 image_width
= image_width
* TILE_SIZE
;
2292 image_height
= VID_MAX_HEIGHT
/ TILE_SIZE
;
2294 if (VID_MAX_HEIGHT
% TILE_SIZE
)
2297 image_height
= image_height
* TILE_SIZE
;
2298 vout
->smsshado_size
= PAGE_ALIGN(image_width
* image_height
* 2 * 2);
2301 * Request and Initialize DMA, for DMA based VRFB transfer
2303 vout
->vrfb_dma_tx
.dev_id
= OMAP_DMA_NO_DEVICE
;
2304 vout
->vrfb_dma_tx
.dma_ch
= -1;
2305 vout
->vrfb_dma_tx
.req_status
= DMA_CHAN_ALLOTED
;
2306 ret
= omap_request_dma(vout
->vrfb_dma_tx
.dev_id
, "VRFB DMA TX",
2307 omap_vout_vrfb_dma_tx_callback
,
2308 (void *) &vout
->vrfb_dma_tx
, &vout
->vrfb_dma_tx
.dma_ch
);
2310 vout
->vrfb_dma_tx
.req_status
= DMA_CHAN_NOT_ALLOTED
;
2311 dev_info(&pdev
->dev
, ": failed to allocate DMA Channel for"
2312 " video%d\n", vfd
->minor
);
2314 init_waitqueue_head(&vout
->vrfb_dma_tx
.wait
);
2316 /* Allocate VRFB buffers if selected through bootargs */
2317 static_vrfb_allocation
= (vid_num
== 0) ?
2318 vid1_static_vrfb_alloc
: vid2_static_vrfb_alloc
;
2320 /* statically allocated the VRFB buffer is done through
2321 commands line aruments */
2322 if (static_vrfb_allocation
) {
2323 if (omap_vout_allocate_vrfb_buffers(vout
, &vrfb_num_bufs
, -1)) {
2325 goto release_vrfb_ctx
;
2327 vout
->vrfb_static_allocation
= 1;
2332 for (j
= 0; j
< VRFB_NUM_BUFS
; j
++)
2333 omap_vrfb_release_ctx(&vout
->vrfb_context
[j
]);
2336 for (i
= 0; i
< numbuffers
; i
++) {
2337 omap_vout_free_buffer(vout
->buf_virt_addr
[i
],
2339 vout
->buf_virt_addr
[i
] = 0;
2340 vout
->buf_phy_addr
[i
] = 0;
2346 /* Create video out devices */
2347 static int __init
omap_vout_create_video_devices(struct platform_device
*pdev
)
2350 struct omap_vout_device
*vout
;
2351 struct video_device
*vfd
= NULL
;
2352 struct v4l2_device
*v4l2_dev
= platform_get_drvdata(pdev
);
2353 struct omap2video_device
*vid_dev
= container_of(v4l2_dev
,
2354 struct omap2video_device
, v4l2_dev
);
2356 for (k
= 0; k
< pdev
->num_resources
; k
++) {
2358 vout
= kzalloc(sizeof(struct omap_vout_device
), GFP_KERNEL
);
2360 dev_err(&pdev
->dev
, ": could not allocate memory\n");
2365 vid_dev
->vouts
[k
] = vout
;
2366 vout
->vid_dev
= vid_dev
;
2367 /* Select video2 if only 1 overlay is controlled by V4L2 */
2368 if (pdev
->num_resources
== 1)
2369 vout
->vid_info
.overlays
[0] = vid_dev
->overlays
[k
+ 2];
2371 /* Else select video1 and video2 one by one. */
2372 vout
->vid_info
.overlays
[0] = vid_dev
->overlays
[k
+ 1];
2373 vout
->vid_info
.num_overlays
= 1;
2374 vout
->vid_info
.id
= k
+ 1;
2376 /* Setup the default configuration for the video devices
2378 if (omap_vout_setup_video_data(vout
) != 0) {
2383 /* Allocate default number of buffers for the video streaming
2384 * and reserve the VRFB space for rotation
2386 if (omap_vout_setup_video_bufs(pdev
, k
) != 0) {
2391 /* Register the Video device with V4L2
2394 if (video_register_device(vfd
, VFL_TYPE_GRABBER
, k
+ 1) < 0) {
2395 dev_err(&pdev
->dev
, ": Could not register "
2396 "Video for Linux device\n");
2401 video_set_drvdata(vfd
, vout
);
2403 /* Configure the overlay structure */
2404 ret
= omapvid_init(vid_dev
->vouts
[k
], 0);
2409 omap_vout_release_vrfb(vout
);
2410 omap_vout_free_buffers(vout
);
2412 video_device_release(vfd
);
2418 dev_info(&pdev
->dev
, ": registered and initialized"
2419 " video device %d\n", vfd
->minor
);
2420 if (k
== (pdev
->num_resources
- 1))
2426 /* Driver functions */
2427 static void omap_vout_cleanup_device(struct omap_vout_device
*vout
)
2429 struct video_device
*vfd
;
2436 if (!video_is_registered(vfd
)) {
2438 * The device was never registered, so release the
2439 * video_device struct directly.
2441 video_device_release(vfd
);
2444 * The unregister function will release the video_device
2445 * struct as well as unregistering it.
2447 video_unregister_device(vfd
);
2451 omap_vout_release_vrfb(vout
);
2452 omap_vout_free_buffers(vout
);
2453 /* Free the VRFB buffer if allocated
2456 if (vout
->vrfb_static_allocation
)
2457 omap_vout_free_vrfb_buffers(vout
);
2462 static int omap_vout_remove(struct platform_device
*pdev
)
2465 struct v4l2_device
*v4l2_dev
= platform_get_drvdata(pdev
);
2466 struct omap2video_device
*vid_dev
= container_of(v4l2_dev
, struct
2467 omap2video_device
, v4l2_dev
);
2469 v4l2_device_unregister(v4l2_dev
);
2470 for (k
= 0; k
< pdev
->num_resources
; k
++)
2471 omap_vout_cleanup_device(vid_dev
->vouts
[k
]);
2473 for (k
= 0; k
< vid_dev
->num_displays
; k
++) {
2474 if (vid_dev
->displays
[k
]->state
!= OMAP_DSS_DISPLAY_DISABLED
)
2475 vid_dev
->displays
[k
]->driver
->disable(vid_dev
->displays
[k
]);
2477 omap_dss_put_device(vid_dev
->displays
[k
]);
2483 static int __init
omap_vout_probe(struct platform_device
*pdev
)
2486 struct omap_overlay
*ovl
;
2487 struct omap_dss_device
*dssdev
= NULL
;
2488 struct omap_dss_device
*def_display
;
2489 struct omap2video_device
*vid_dev
= NULL
;
2491 if (pdev
->num_resources
== 0) {
2492 dev_err(&pdev
->dev
, "probed for an unknown device\n");
2496 vid_dev
= kzalloc(sizeof(struct omap2video_device
), GFP_KERNEL
);
2497 if (vid_dev
== NULL
)
2500 vid_dev
->num_displays
= 0;
2501 for_each_dss_dev(dssdev
) {
2502 omap_dss_get_device(dssdev
);
2503 vid_dev
->displays
[vid_dev
->num_displays
++] = dssdev
;
2506 if (vid_dev
->num_displays
== 0) {
2507 dev_err(&pdev
->dev
, "no displays\n");
2512 vid_dev
->num_overlays
= omap_dss_get_num_overlays();
2513 for (i
= 0; i
< vid_dev
->num_overlays
; i
++)
2514 vid_dev
->overlays
[i
] = omap_dss_get_overlay(i
);
2516 vid_dev
->num_managers
= omap_dss_get_num_overlay_managers();
2517 for (i
= 0; i
< vid_dev
->num_managers
; i
++)
2518 vid_dev
->managers
[i
] = omap_dss_get_overlay_manager(i
);
2520 /* Get the Video1 overlay and video2 overlay.
2521 * Setup the Display attached to that overlays
2523 for (i
= 1; i
< vid_dev
->num_overlays
; i
++) {
2524 ovl
= omap_dss_get_overlay(i
);
2525 if (ovl
->manager
&& ovl
->manager
->device
) {
2526 def_display
= ovl
->manager
->device
;
2528 dev_warn(&pdev
->dev
, "cannot find display\n");
2532 struct omap_dss_driver
*dssdrv
= def_display
->driver
;
2534 ret
= dssdrv
->enable(def_display
);
2536 /* Here we are not considering a error
2537 * as display may be enabled by frame
2540 dev_warn(&pdev
->dev
,
2541 "'%s' Display already enabled\n",
2544 /* set the update mode */
2545 if (def_display
->caps
&
2546 OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE
) {
2547 if (dssdrv
->enable_te
)
2548 dssdrv
->enable_te(def_display
, 0);
2549 if (dssdrv
->set_update_mode
)
2550 dssdrv
->set_update_mode(def_display
,
2551 OMAP_DSS_UPDATE_MANUAL
);
2553 if (dssdrv
->set_update_mode
)
2554 dssdrv
->set_update_mode(def_display
,
2555 OMAP_DSS_UPDATE_AUTO
);
2560 if (v4l2_device_register(&pdev
->dev
, &vid_dev
->v4l2_dev
) < 0) {
2561 dev_err(&pdev
->dev
, "v4l2_device_register failed\n");
2566 ret
= omap_vout_create_video_devices(pdev
);
2570 for (i
= 0; i
< vid_dev
->num_displays
; i
++) {
2571 struct omap_dss_device
*display
= vid_dev
->displays
[i
];
2573 if (display
->driver
->update
)
2574 display
->driver
->update(display
, 0, 0,
2575 display
->panel
.timings
.x_res
,
2576 display
->panel
.timings
.y_res
);
2581 v4l2_device_unregister(&vid_dev
->v4l2_dev
);
2583 for (i
= 1; i
< vid_dev
->num_overlays
; i
++) {
2585 ovl
= omap_dss_get_overlay(i
);
2586 if (ovl
->manager
&& ovl
->manager
->device
)
2587 def_display
= ovl
->manager
->device
;
2589 if (def_display
&& def_display
->driver
)
2590 def_display
->driver
->disable(def_display
);
2597 static struct platform_driver omap_vout_driver
= {
2601 .probe
= omap_vout_probe
,
2602 .remove
= omap_vout_remove
,
2605 static int __init
omap_vout_init(void)
2607 if (platform_driver_register(&omap_vout_driver
) != 0) {
2608 printk(KERN_ERR VOUT_NAME
":Could not register Video driver\n");
2614 static void omap_vout_cleanup(void)
2616 platform_driver_unregister(&omap_vout_driver
);
2619 late_initcall(omap_vout_init
);
2620 module_exit(omap_vout_cleanup
);