aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/omap/omap_vout.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/omap/omap_vout.c')
-rw-r--r--drivers/media/video/omap/omap_vout.c645
1 files changed, 141 insertions, 504 deletions
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index a647894d3a71..b5ef36222440 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -35,28 +35,26 @@
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/types.h> 36#include <linux/types.h>
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/dma-mapping.h>
39#include <linux/irq.h> 38#include <linux/irq.h>
40#include <linux/videodev2.h> 39#include <linux/videodev2.h>
41#include <linux/slab.h> 40#include <linux/dma-mapping.h>
42 41
43#include <media/videobuf-dma-contig.h> 42#include <media/videobuf-dma-contig.h>
44#include <media/v4l2-device.h> 43#include <media/v4l2-device.h>
45#include <media/v4l2-ioctl.h> 44#include <media/v4l2-ioctl.h>
46 45
47#include <plat/dma.h> 46#include <plat/dma.h>
48#include <plat/vram.h>
49#include <plat/vrfb.h> 47#include <plat/vrfb.h>
50#include <video/omapdss.h> 48#include <video/omapdss.h>
51 49
52#include "omap_voutlib.h" 50#include "omap_voutlib.h"
53#include "omap_voutdef.h" 51#include "omap_voutdef.h"
52#include "omap_vout_vrfb.h"
54 53
55MODULE_AUTHOR("Texas Instruments"); 54MODULE_AUTHOR("Texas Instruments");
56MODULE_DESCRIPTION("OMAP Video for Linux Video out driver"); 55MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
57MODULE_LICENSE("GPL"); 56MODULE_LICENSE("GPL");
58 57
59
60/* Driver Configuration macros */ 58/* Driver Configuration macros */
61#define VOUT_NAME "omap_vout" 59#define VOUT_NAME "omap_vout"
62 60
@@ -65,31 +63,6 @@ enum omap_vout_channels {
65 OMAP_VIDEO2, 63 OMAP_VIDEO2,
66}; 64};
67 65
68enum dma_channel_state {
69 DMA_CHAN_NOT_ALLOTED,
70 DMA_CHAN_ALLOTED,
71};
72
73#define QQVGA_WIDTH 160
74#define QQVGA_HEIGHT 120
75
76/* Max Resolution supported by the driver */
77#define VID_MAX_WIDTH 1280 /* Largest width */
78#define VID_MAX_HEIGHT 720 /* Largest height */
79
80/* Mimimum requirement is 2x2 for DSS */
81#define VID_MIN_WIDTH 2
82#define VID_MIN_HEIGHT 2
83
84/* 2048 x 2048 is max res supported by OMAP display controller */
85#define MAX_PIXELS_PER_LINE 2048
86
87#define VRFB_TX_TIMEOUT 1000
88#define VRFB_NUM_BUFS 4
89
90/* Max buffer size tobe allocated during init */
91#define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4)
92
93static struct videobuf_queue_ops video_vbq_ops; 66static struct videobuf_queue_ops video_vbq_ops;
94/* Variables configurable through module params*/ 67/* Variables configurable through module params*/
95static u32 video1_numbuffers = 3; 68static u32 video1_numbuffers = 3;
@@ -172,84 +145,6 @@ static const struct v4l2_fmtdesc omap_formats[] = {
172#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats)) 145#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
173 146
174/* 147/*
175 * Allocate buffers
176 */
177static unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr)
178{
179 u32 order, size;
180 unsigned long virt_addr, addr;
181
182 size = PAGE_ALIGN(buf_size);
183 order = get_order(size);
184 virt_addr = __get_free_pages(GFP_KERNEL | GFP_DMA, order);
185 addr = virt_addr;
186
187 if (virt_addr) {
188 while (size > 0) {
189 SetPageReserved(virt_to_page(addr));
190 addr += PAGE_SIZE;
191 size -= PAGE_SIZE;
192 }
193 }
194 *phys_addr = (u32) virt_to_phys((void *) virt_addr);
195 return virt_addr;
196}
197
198/*
199 * Free buffers
200 */
201static void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size)
202{
203 u32 order, size;
204 unsigned long addr = virtaddr;
205
206 size = PAGE_ALIGN(buf_size);
207 order = get_order(size);
208
209 while (size > 0) {
210 ClearPageReserved(virt_to_page(addr));
211 addr += PAGE_SIZE;
212 size -= PAGE_SIZE;
213 }
214 free_pages((unsigned long) virtaddr, order);
215}
216
217/*
218 * Function for allocating video buffers
219 */
220static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout,
221 unsigned int *count, int startindex)
222{
223 int i, j;
224
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]);
230 }
231 if (!vout->smsshado_virt_addr[i] && startindex != -1) {
232 if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex)
233 break;
234 }
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;
242 }
243 *count = 0;
244 return -ENOMEM;
245 }
246 memset((void *) vout->smsshado_virt_addr[i], 0,
247 vout->smsshado_size);
248 }
249 return 0;
250}
251
252/*
253 * Try format 148 * Try format
254 */ 149 */
255static int omap_vout_try_format(struct v4l2_pix_format *pix) 150static int omap_vout_try_format(struct v4l2_pix_format *pix)
@@ -342,73 +237,9 @@ static u32 omap_vout_uservirt_to_phys(u32 virtp)
342} 237}
343 238
344/* 239/*
345 * Wakes up the application once the DMA transfer to VRFB space is completed.
346 */
347static void omap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data)
348{
349 struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data;
350
351 t->tx_status = 1;
352 wake_up_interruptible(&t->wait);
353}
354
355/*
356 * Release the VRFB context once the module exits
357 */
358static void omap_vout_release_vrfb(struct omap_vout_device *vout)
359{
360 int i;
361
362 for (i = 0; i < VRFB_NUM_BUFS; i++)
363 omap_vrfb_release_ctx(&vout->vrfb_context[i]);
364
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);
368 }
369}
370
371/*
372 * Return true if rotation is 90 or 270
373 */
374static inline int rotate_90_or_270(const struct omap_vout_device *vout)
375{
376 return (vout->rotation == dss_rotation_90_degree ||
377 vout->rotation == dss_rotation_270_degree);
378}
379
380/*
381 * Return true if rotation is enabled
382 */
383static inline int rotation_enabled(const struct omap_vout_device *vout)
384{
385 return vout->rotation || vout->mirror;
386}
387
388/*
389 * Reverse the rotation degree if mirroring is enabled
390 */
391static inline int calc_rotation(const struct omap_vout_device *vout)
392{
393 if (!vout->mirror)
394 return vout->rotation;
395
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;
403 default:
404 return dss_rotation_180_degree;
405 }
406}
407
408/*
409 * Free the V4L2 buffers 240 * Free the V4L2 buffers
410 */ 241 */
411static void omap_vout_free_buffers(struct omap_vout_device *vout) 242void omap_vout_free_buffers(struct omap_vout_device *vout)
412{ 243{
413 int i, numbuffers; 244 int i, numbuffers;
414 245
@@ -425,52 +256,6 @@ static void omap_vout_free_buffers(struct omap_vout_device *vout)
425} 256}
426 257
427/* 258/*
428 * Free VRFB buffers
429 */
430static void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout)
431{
432 int j;
433
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;
439 }
440}
441
442/*
443 * Allocate the buffers for the VRFB space. Data is copied from V4L2
444 * buffers to the VRFB buffers using the DMA engine.
445 */
446static int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
447 unsigned int *count, unsigned int startindex)
448{
449 int i;
450 bool yuv_mode;
451
452 /* Allocate the VRFB buffers only if the buffers are not
453 * allocated during init time.
454 */
455 if ((rotation_enabled(vout)) && !vout->vrfb_static_allocation)
456 if (omap_vout_allocate_vrfb_buffers(vout, count, startindex))
457 return -ENOMEM;
458
459 if (vout->dss_mode == OMAP_DSS_COLOR_YUV2 ||
460 vout->dss_mode == OMAP_DSS_COLOR_UYVY)
461 yuv_mode = true;
462 else
463 yuv_mode = false;
464
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);
469
470 return 0;
471}
472
473/*
474 * Convert V4L2 rotation to DSS rotation 259 * Convert V4L2 rotation to DSS rotation
475 * V4L2 understand 0, 90, 180, 270. 260 * V4L2 understand 0, 90, 180, 270.
476 * Convert to 0, 1, 2 and 3 respectively for DSS 261 * Convert to 0, 1, 2 and 3 respectively for DSS
@@ -499,124 +284,38 @@ static int v4l2_rot_to_dss_rot(int v4l2_rotation,
499 return ret; 284 return ret;
500} 285}
501 286
502/*
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.
506 */
507static int omap_vout_calculate_offset(struct omap_vout_device *vout) 287static int omap_vout_calculate_offset(struct omap_vout_device *vout)
508{ 288{
509 struct omap_overlay *ovl;
510 enum dss_rotation rotation;
511 struct omapvideo_info *ovid; 289 struct omapvideo_info *ovid;
512 bool mirroring = vout->mirror;
513 struct omap_dss_device *cur_display;
514 struct v4l2_rect *crop = &vout->crop; 290 struct v4l2_rect *crop = &vout->crop;
515 struct v4l2_pix_format *pix = &vout->pix; 291 struct v4l2_pix_format *pix = &vout->pix;
516 int *cropped_offset = &vout->cropped_offset; 292 int *cropped_offset = &vout->cropped_offset;
517 int vr_ps = 1, ps = 2, temp_ps = 2; 293 int ps = 2, line_length = 0;
518 int offset = 0, ctop = 0, cleft = 0, line_length = 0;
519 294
520 ovid = &vout->vid_info; 295 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)
524 return -1;
525 296
526 cur_display = ovl->manager->device; 297 if (ovid->rotation_type == VOUT_ROT_VRFB) {
527 rotation = calc_rotation(vout); 298 omap_vout_calculate_vrfb_offset(vout);
299 } else {
300 vout->line_length = line_length = pix->width;
528 301
529 if (V4L2_PIX_FMT_YUYV == pix->pixelformat || 302 if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
530 V4L2_PIX_FMT_UYVY == pix->pixelformat) { 303 V4L2_PIX_FMT_UYVY == pix->pixelformat)
531 if (rotation_enabled(vout)) { 304 ps = 2;
532 /* 305 else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat)
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
536 * 2 bytes
537 */
538 ps = 4; 306 ps = 4;
539 vr_ps = 2; 307 else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat)
540 } else { 308 ps = 3;
541 ps = 2; /* otherwise the pixel size is 2 byte */
542 }
543 } else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) {
544 ps = 4;
545 } else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) {
546 ps = 3;
547 }
548 vout->ps = ps;
549 vout->vr_ps = vr_ps;
550
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;
555 } else {
556 line_length = pix->width;
557 }
558 vout->line_length = line_length;
559 switch (rotation) {
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;
567 } else {
568 *cropped_offset = offset + line_length * temp_ps *
569 cleft + crop->top * temp_ps + (line_length *
570 ((crop->width / (vr_ps)) - 1) * ps);
571 }
572 break;
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;
581 309
582 } else { 310 vout->ps = ps;
583 *cropped_offset = offset + (line_length * ps * ctop) + 311
584 (cleft / vr_ps) * ps + (line_length * 312 *cropped_offset = (line_length * ps) *
585 (crop->height - 1) * ps); 313 crop->top + crop->left * ps;
586 }
587 break;
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;
595 } else {
596 *cropped_offset = offset + line_length *
597 temp_ps * crop->left + ctop * ps +
598 (line_length * ((crop->width / vr_ps) - 1) *
599 ps);
600 }
601 break;
602 case dss_rotation_0_degree:
603 if (mirroring == 0) {
604 *cropped_offset = (line_length * ps) *
605 crop->top + (crop->left / vr_ps) * ps;
606 } else {
607 *cropped_offset = (line_length * ps) *
608 crop->top + (crop->left / vr_ps) * ps +
609 (line_length * (crop->height - 1) * ps);
610 }
611 break;
612 default:
613 *cropped_offset = (line_length * ps * crop->top) /
614 vr_ps + (crop->left * ps) / vr_ps +
615 ((crop->width / vr_ps) - 1) * ps;
616 break;
617 } 314 }
315
618 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n", 316 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n",
619 __func__, *cropped_offset); 317 __func__, vout->cropped_offset);
318
620 return 0; 319 return 0;
621} 320}
622 321
@@ -664,7 +363,7 @@ static int video_mode_to_dss_mode(struct omap_vout_device *vout)
664/* 363/*
665 * Setup the overlay 364 * Setup the overlay
666 */ 365 */
667int omapvid_setup_overlay(struct omap_vout_device *vout, 366static int omapvid_setup_overlay(struct omap_vout_device *vout,
668 struct omap_overlay *ovl, int posx, int posy, int outw, 367 struct omap_overlay *ovl, int posx, int posy, int outw,
669 int outh, u32 addr) 368 int outh, u32 addr)
670{ 369{
@@ -687,7 +386,7 @@ int omapvid_setup_overlay(struct omap_vout_device *vout,
687 /* Setup the input plane parameters according to 386 /* Setup the input plane parameters according to
688 * rotation value selected. 387 * rotation value selected.
689 */ 388 */
690 if (rotate_90_or_270(vout)) { 389 if (is_rotation_90_or_270(vout)) {
691 cropheight = vout->crop.width; 390 cropheight = vout->crop.width;
692 cropwidth = vout->crop.height; 391 cropwidth = vout->crop.height;
693 pixheight = vout->pix.width; 392 pixheight = vout->pix.width;
@@ -711,7 +410,7 @@ int omapvid_setup_overlay(struct omap_vout_device *vout,
711 info.out_width = outw; 410 info.out_width = outw;
712 info.out_height = outh; 411 info.out_height = outh;
713 info.global_alpha = vout->win.global_alpha; 412 info.global_alpha = vout->win.global_alpha;
714 if (!rotation_enabled(vout)) { 413 if (!is_rotation_enabled(vout)) {
715 info.rotation = 0; 414 info.rotation = 0;
716 info.rotation_type = OMAP_DSS_ROT_DMA; 415 info.rotation_type = OMAP_DSS_ROT_DMA;
717 info.screen_width = pixwidth; 416 info.screen_width = pixwidth;
@@ -744,7 +443,7 @@ setup_ovl_err:
744/* 443/*
745 * Initialize the overlay structure 444 * Initialize the overlay structure
746 */ 445 */
747int omapvid_init(struct omap_vout_device *vout, u32 addr) 446static int omapvid_init(struct omap_vout_device *vout, u32 addr)
748{ 447{
749 int ret = 0, i; 448 int ret = 0, i;
750 struct v4l2_window *win; 449 struct v4l2_window *win;
@@ -809,7 +508,7 @@ omapvid_init_err:
809/* 508/*
810 * Apply the changes set the go bit of DSS 509 * Apply the changes set the go bit of DSS
811 */ 510 */
812int omapvid_apply_changes(struct omap_vout_device *vout) 511static int omapvid_apply_changes(struct omap_vout_device *vout)
813{ 512{
814 int i; 513 int i;
815 struct omap_overlay *ovl; 514 struct omap_overlay *ovl;
@@ -825,7 +524,7 @@ int omapvid_apply_changes(struct omap_vout_device *vout)
825 return 0; 524 return 0;
826} 525}
827 526
828void omap_vout_isr(void *arg, unsigned int irqstatus) 527static void omap_vout_isr(void *arg, unsigned int irqstatus)
829{ 528{
830 int ret; 529 int ret;
831 u32 addr, fid; 530 u32 addr, fid;
@@ -848,10 +547,20 @@ void omap_vout_isr(void *arg, unsigned int irqstatus)
848 547
849 spin_lock(&vout->vbq_lock); 548 spin_lock(&vout->vbq_lock);
850 do_gettimeofday(&timevalue); 549 do_gettimeofday(&timevalue);
851 if (cur_display->type == OMAP_DISPLAY_TYPE_DPI) {
852 if (!(irqstatus & DISPC_IRQ_VSYNC))
853 goto vout_isr_err;
854 550
551 if (cur_display->type != OMAP_DISPLAY_TYPE_VENC) {
552 switch (cur_display->type) {
553 case OMAP_DISPLAY_TYPE_DPI:
554 if (!(irqstatus & (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2)))
555 goto vout_isr_err;
556 break;
557 case OMAP_DISPLAY_TYPE_HDMI:
558 if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
559 goto vout_isr_err;
560 break;
561 default:
562 goto vout_isr_err;
563 }
855 if (!vout->first_int && (vout->cur_frm != vout->next_frm)) { 564 if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
856 vout->cur_frm->ts = timevalue; 565 vout->cur_frm->ts = timevalue;
857 vout->cur_frm->state = VIDEOBUF_DONE; 566 vout->cur_frm->state = VIDEOBUF_DONE;
@@ -875,7 +584,7 @@ void omap_vout_isr(void *arg, unsigned int irqstatus)
875 ret = omapvid_init(vout, addr); 584 ret = omapvid_init(vout, addr);
876 if (ret) 585 if (ret)
877 printk(KERN_ERR VOUT_NAME 586 printk(KERN_ERR VOUT_NAME
878 "failed to set overlay info\n"); 587 "failed to set overlay info\n");
879 /* Enable the pipeline and set the Go bit */ 588 /* Enable the pipeline and set the Go bit */
880 ret = omapvid_apply_changes(vout); 589 ret = omapvid_apply_changes(vout);
881 if (ret) 590 if (ret)
@@ -954,6 +663,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
954 int startindex = 0, i, j; 663 int startindex = 0, i, j;
955 u32 phy_addr = 0, virt_addr = 0; 664 u32 phy_addr = 0, virt_addr = 0;
956 struct omap_vout_device *vout = q->priv_data; 665 struct omap_vout_device *vout = q->priv_data;
666 struct omapvideo_info *ovid = &vout->vid_info;
957 667
958 if (!vout) 668 if (!vout)
959 return -EINVAL; 669 return -EINVAL;
@@ -966,13 +676,10 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
966 if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex) 676 if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
967 *count = startindex; 677 *count = startindex;
968 678
969 if ((rotation_enabled(vout)) && *count > VRFB_NUM_BUFS) 679 if (ovid->rotation_type == VOUT_ROT_VRFB) {
970 *count = VRFB_NUM_BUFS;
971
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)) 680 if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
975 return -ENOMEM; 681 return -ENOMEM;
682 }
976 683
977 if (V4L2_MEMORY_MMAP != vout->memory) 684 if (V4L2_MEMORY_MMAP != vout->memory)
978 return 0; 685 return 0;
@@ -996,8 +703,11 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
996 virt_addr = omap_vout_alloc_buffer(vout->buffer_size, 703 virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
997 &phy_addr); 704 &phy_addr);
998 if (!virt_addr) { 705 if (!virt_addr) {
999 if (!rotation_enabled(vout)) 706 if (ovid->rotation_type == VOUT_ROT_NONE) {
1000 break; 707 break;
708 } else {
709 if (!is_rotation_enabled(vout))
710 break;
1001 /* Free the VRFB buffers if no space for V4L2 buffers */ 711 /* Free the VRFB buffers if no space for V4L2 buffers */
1002 for (j = i; j < *count; j++) { 712 for (j = i; j < *count; j++) {
1003 omap_vout_free_buffer( 713 omap_vout_free_buffer(
@@ -1005,6 +715,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
1005 vout->smsshado_size); 715 vout->smsshado_size);
1006 vout->smsshado_virt_addr[j] = 0; 716 vout->smsshado_virt_addr[j] = 0;
1007 vout->smsshado_phy_addr[j] = 0; 717 vout->smsshado_phy_addr[j] = 0;
718 }
1008 } 719 }
1009 } 720 }
1010 vout->buf_virt_addr[i] = virt_addr; 721 vout->buf_virt_addr[i] = virt_addr;
@@ -1017,9 +728,9 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
1017 728
1018/* 729/*
1019 * Free the V4L2 buffers additionally allocated than default 730 * Free the V4L2 buffers additionally allocated than default
1020 * number of buffers and free all the VRFB buffers 731 * number of buffers
1021 */ 732 */
1022static void omap_vout_free_allbuffers(struct omap_vout_device *vout) 733static void omap_vout_free_extra_buffers(struct omap_vout_device *vout)
1023{ 734{
1024 int num_buffers = 0, i; 735 int num_buffers = 0, i;
1025 736
@@ -1034,20 +745,6 @@ static void omap_vout_free_allbuffers(struct omap_vout_device *vout)
1034 vout->buf_virt_addr[i] = 0; 745 vout->buf_virt_addr[i] = 0;
1035 vout->buf_phy_addr[i] = 0; 746 vout->buf_phy_addr[i] = 0;
1036 } 747 }
1037 /* Free the VRFB buffers only if they are allocated
1038 * during reqbufs. Don't free if init time allocated
1039 */
1040 if (!vout->vrfb_static_allocation) {
1041 for (i = 0; i < VRFB_NUM_BUFS; i++) {
1042 if (vout->smsshado_virt_addr[i]) {
1043 omap_vout_free_buffer(
1044 vout->smsshado_virt_addr[i],
1045 vout->smsshado_size);
1046 vout->smsshado_virt_addr[i] = 0;
1047 vout->smsshado_phy_addr[i] = 0;
1048 }
1049 }
1050 }
1051 vout->buffer_allocated = num_buffers; 748 vout->buffer_allocated = num_buffers;
1052} 749}
1053 750
@@ -1059,16 +756,11 @@ static void omap_vout_free_allbuffers(struct omap_vout_device *vout)
1059 * buffer into VRFB memory space before giving it to the DSS. 756 * buffer into VRFB memory space before giving it to the DSS.
1060 */ 757 */
1061static int omap_vout_buffer_prepare(struct videobuf_queue *q, 758static int omap_vout_buffer_prepare(struct videobuf_queue *q,
1062 struct videobuf_buffer *vb, 759 struct videobuf_buffer *vb,
1063 enum v4l2_field field) 760 enum v4l2_field field)
1064{ 761{
1065 dma_addr_t dmabuf;
1066 struct vid_vrfb_dma *tx;
1067 enum dss_rotation rotation;
1068 struct omap_vout_device *vout = q->priv_data; 762 struct omap_vout_device *vout = q->priv_data;
1069 u32 dest_frame_index = 0, src_element_index = 0; 763 struct omapvideo_info *ovid = &vout->vid_info;
1070 u32 dest_element_index = 0, src_frame_index = 0;
1071 u32 elem_count = 0, frame_count = 0, pixsize = 2;
1072 764
1073 if (VIDEOBUF_NEEDS_INIT == vb->state) { 765 if (VIDEOBUF_NEEDS_INIT == vb->state) {
1074 vb->width = vout->pix.width; 766 vb->width = vout->pix.width;
@@ -1087,66 +779,24 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q,
1087 vout->queued_buf_addr[vb->i] = (u8 *) 779 vout->queued_buf_addr[vb->i] = (u8 *)
1088 omap_vout_uservirt_to_phys(vb->baddr); 780 omap_vout_uservirt_to_phys(vb->baddr);
1089 } else { 781 } else {
1090 vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i]; 782 u32 addr, dma_addr;
1091 } 783 unsigned long size;
1092 784
1093 if (!rotation_enabled(vout)) 785 addr = (unsigned long) vout->buf_virt_addr[vb->i];
1094 return 0; 786 size = (unsigned long) vb->size;
1095 787
1096 dmabuf = vout->buf_phy_addr[vb->i]; 788 dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr,
1097 /* If rotation is enabled, copy input buffer into VRFB 789 size, DMA_TO_DEVICE);
1098 * memory space using DMA. We are copying input buffer 790 if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr))
1099 * into VRFB memory space of desired angle and DSS will 791 v4l2_err(&vout->vid_dev->v4l2_dev, "dma_map_single failed\n");
1100 * read image VRFB memory for 0 degree angle
1101 */
1102 pixsize = vout->bpp * vout->vrfb_bpp;
1103 /*
1104 * DMA transfer in double index mode
1105 */
1106 792
1107 /* Frame index */ 793 vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i];
1108 dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) -
1109 (vout->pix.width * vout->bpp)) + 1;
1110
1111 /* Source and destination parameters */
1112 src_element_index = 0;
1113 src_frame_index = 0;
1114 dest_element_index = 1;
1115 /* Number of elements per frame */
1116 elem_count = vout->pix.width * vout->bpp;
1117 frame_count = vout->pix.height;
1118 tx = &vout->vrfb_dma_tx;
1119 tx->tx_status = 0;
1120 omap_set_dma_transfer_params(tx->dma_ch, OMAP_DMA_DATA_TYPE_S32,
1121 (elem_count / 4), frame_count, OMAP_DMA_SYNC_ELEMENT,
1122 tx->dev_id, 0x0);
1123 /* src_port required only for OMAP1 */
1124 omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
1125 dmabuf, src_element_index, src_frame_index);
1126 /*set dma source burst mode for VRFB */
1127 omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
1128 rotation = calc_rotation(vout);
1129
1130 /* dest_port required only for OMAP1 */
1131 omap_set_dma_dest_params(tx->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
1132 vout->vrfb_context[vb->i].paddr[0], dest_element_index,
1133 dest_frame_index);
1134 /*set dma dest burst mode for VRFB */
1135 omap_set_dma_dest_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
1136 omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);
1137
1138 omap_start_dma(tx->dma_ch);
1139 interruptible_sleep_on_timeout(&tx->wait, VRFB_TX_TIMEOUT);
1140
1141 if (tx->tx_status == 0) {
1142 omap_stop_dma(tx->dma_ch);
1143 return -EINVAL;
1144 } 794 }
1145 /* Store buffers physical address into an array. Addresses 795
1146 * from this array will be used to configure DSS */ 796 if (ovid->rotation_type == VOUT_ROT_VRFB)
1147 vout->queued_buf_addr[vb->i] = (u8 *) 797 return omap_vout_prepare_vrfb(vout, vb);
1148 vout->vrfb_context[vb->i].paddr[rotation]; 798 else
1149 return 0; 799 return 0;
1150} 800}
1151 801
1152/* 802/*
@@ -1298,7 +948,15 @@ static int omap_vout_release(struct file *file)
1298 "Unable to apply changes\n"); 948 "Unable to apply changes\n");
1299 949
1300 /* Free all buffers */ 950 /* Free all buffers */
1301 omap_vout_free_allbuffers(vout); 951 omap_vout_free_extra_buffers(vout);
952
953 /* Free the VRFB buffers only if they are allocated
954 * during reqbufs. Don't free if init time allocated
955 */
956 if (ovid->rotation_type == VOUT_ROT_VRFB) {
957 if (!vout->vrfb_static_allocation)
958 omap_vout_free_vrfb_buffers(vout);
959 }
1302 videobuf_mmap_free(q); 960 videobuf_mmap_free(q);
1303 961
1304 /* Even if apply changes fails we should continue 962 /* Even if apply changes fails we should continue
@@ -1307,7 +965,7 @@ static int omap_vout_release(struct file *file)
1307 u32 mask = 0; 965 u32 mask = 0;
1308 966
1309 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | 967 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
1310 DISPC_IRQ_EVSYNC_ODD; 968 DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2;
1311 omap_dispc_unregister_isr(omap_vout_isr, vout, mask); 969 omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
1312 vout->streaming = 0; 970 vout->streaming = 0;
1313 971
@@ -1383,10 +1041,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
1383 struct v4l2_fmtdesc *fmt) 1041 struct v4l2_fmtdesc *fmt)
1384{ 1042{
1385 int index = fmt->index; 1043 int index = fmt->index;
1386 enum v4l2_buf_type type = fmt->type;
1387 1044
1388 fmt->index = index;
1389 fmt->type = type;
1390 if (index >= NUM_OUTPUT_FORMATS) 1045 if (index >= NUM_OUTPUT_FORMATS)
1391 return -EINVAL; 1046 return -EINVAL;
1392 1047
@@ -1457,7 +1112,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
1457 1112
1458 /* We dont support RGB24-packed mode if vrfb rotation 1113 /* We dont support RGB24-packed mode if vrfb rotation
1459 * is enabled*/ 1114 * is enabled*/
1460 if ((rotation_enabled(vout)) && 1115 if ((is_rotation_enabled(vout)) &&
1461 f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) { 1116 f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1462 ret = -EINVAL; 1117 ret = -EINVAL;
1463 goto s_fmt_vid_out_exit; 1118 goto s_fmt_vid_out_exit;
@@ -1465,7 +1120,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
1465 1120
1466 /* get the framebuffer parameters */ 1121 /* get the framebuffer parameters */
1467 1122
1468 if (rotate_90_or_270(vout)) { 1123 if (is_rotation_90_or_270(vout)) {
1469 vout->fbuf.fmt.height = timing->x_res; 1124 vout->fbuf.fmt.height = timing->x_res;
1470 vout->fbuf.fmt.width = timing->y_res; 1125 vout->fbuf.fmt.width = timing->y_res;
1471 } else { 1126 } else {
@@ -1555,10 +1210,7 @@ static int vidioc_enum_fmt_vid_overlay(struct file *file, void *fh,
1555 struct v4l2_fmtdesc *fmt) 1210 struct v4l2_fmtdesc *fmt)
1556{ 1211{
1557 int index = fmt->index; 1212 int index = fmt->index;
1558 enum v4l2_buf_type type = fmt->type;
1559 1213
1560 fmt->index = index;
1561 fmt->type = type;
1562 if (index >= NUM_OUTPUT_FORMATS) 1214 if (index >= NUM_OUTPUT_FORMATS)
1563 return -EINVAL; 1215 return -EINVAL;
1564 1216
@@ -1645,7 +1297,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1645 /* get the display device attached to the overlay */ 1297 /* get the display device attached to the overlay */
1646 timing = &ovl->manager->device->panel.timings; 1298 timing = &ovl->manager->device->panel.timings;
1647 1299
1648 if (rotate_90_or_270(vout)) { 1300 if (is_rotation_90_or_270(vout)) {
1649 vout->fbuf.fmt.height = timing->x_res; 1301 vout->fbuf.fmt.height = timing->x_res;
1650 vout->fbuf.fmt.width = timing->y_res; 1302 vout->fbuf.fmt.width = timing->y_res;
1651 } else { 1303 } else {
@@ -1725,9 +1377,17 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
1725 switch (a->id) { 1377 switch (a->id) {
1726 case V4L2_CID_ROTATE: 1378 case V4L2_CID_ROTATE:
1727 { 1379 {
1380 struct omapvideo_info *ovid;
1728 int rotation = a->value; 1381 int rotation = a->value;
1729 1382
1383 ovid = &vout->vid_info;
1384
1730 mutex_lock(&vout->lock); 1385 mutex_lock(&vout->lock);
1386 if (rotation && ovid->rotation_type == VOUT_ROT_NONE) {
1387 mutex_unlock(&vout->lock);
1388 ret = -ERANGE;
1389 break;
1390 }
1731 1391
1732 if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { 1392 if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1733 mutex_unlock(&vout->lock); 1393 mutex_unlock(&vout->lock);
@@ -1783,6 +1443,11 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
1783 ovl = ovid->overlays[0]; 1443 ovl = ovid->overlays[0];
1784 1444
1785 mutex_lock(&vout->lock); 1445 mutex_lock(&vout->lock);
1446 if (mirror && ovid->rotation_type == VOUT_ROT_NONE) {
1447 mutex_unlock(&vout->lock);
1448 ret = -ERANGE;
1449 break;
1450 }
1786 1451
1787 if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { 1452 if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1788 mutex_unlock(&vout->lock); 1453 mutex_unlock(&vout->lock);
@@ -1893,7 +1558,7 @@ static int vidioc_qbuf(struct file *file, void *fh,
1893 } 1558 }
1894 } 1559 }
1895 1560
1896 if ((rotation_enabled(vout)) && 1561 if ((is_rotation_enabled(vout)) &&
1897 vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) { 1562 vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) {
1898 v4l2_warn(&vout->vid_dev->v4l2_dev, 1563 v4l2_warn(&vout->vid_dev->v4l2_dev,
1899 "DMA Channel not allocated for Rotation\n"); 1564 "DMA Channel not allocated for Rotation\n");
@@ -1908,15 +1573,28 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1908 struct omap_vout_device *vout = fh; 1573 struct omap_vout_device *vout = fh;
1909 struct videobuf_queue *q = &vout->vbq; 1574 struct videobuf_queue *q = &vout->vbq;
1910 1575
1576 int ret;
1577 u32 addr;
1578 unsigned long size;
1579 struct videobuf_buffer *vb;
1580
1581 vb = q->bufs[b->index];
1582
1911 if (!vout->streaming) 1583 if (!vout->streaming)
1912 return -EINVAL; 1584 return -EINVAL;
1913 1585
1914 if (file->f_flags & O_NONBLOCK) 1586 if (file->f_flags & O_NONBLOCK)
1915 /* Call videobuf_dqbuf for non blocking mode */ 1587 /* Call videobuf_dqbuf for non blocking mode */
1916 return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1); 1588 ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
1917 else 1589 else
1918 /* Call videobuf_dqbuf for blocking mode */ 1590 /* Call videobuf_dqbuf for blocking mode */
1919 return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0); 1591 ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
1592
1593 addr = (unsigned long) vout->buf_phy_addr[vb->i];
1594 size = (unsigned long) vb->size;
1595 dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr,
1596 size, DMA_TO_DEVICE);
1597 return ret;
1920} 1598}
1921 1599
1922static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) 1600static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
@@ -1965,7 +1643,8 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1965 addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i] 1643 addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i]
1966 + vout->cropped_offset; 1644 + vout->cropped_offset;
1967 1645
1968 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD; 1646 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1647 | DISPC_IRQ_VSYNC2;
1969 1648
1970 omap_dispc_register_isr(omap_vout_isr, vout, mask); 1649 omap_dispc_register_isr(omap_vout_isr, vout, mask);
1971 1650
@@ -2015,7 +1694,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
2015 return -EINVAL; 1694 return -EINVAL;
2016 1695
2017 vout->streaming = 0; 1696 vout->streaming = 0;
2018 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD; 1697 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1698 | DISPC_IRQ_VSYNC2;
2019 1699
2020 omap_dispc_unregister_isr(omap_vout_isr, vout, mask); 1700 omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
2021 1701
@@ -2228,7 +1908,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
2228 vout->mirror = 0; 1908 vout->mirror = 0;
2229 vout->control[2].id = V4L2_CID_HFLIP; 1909 vout->control[2].id = V4L2_CID_HFLIP;
2230 vout->control[2].value = 0; 1910 vout->control[2].value = 0;
2231 vout->vrfb_bpp = 2; 1911 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
1912 vout->vrfb_bpp = 2;
2232 1913
2233 control[1].id = V4L2_CID_BG_COLOR; 1914 control[1].id = V4L2_CID_BG_COLOR;
2234 control[1].value = 0; 1915 control[1].value = 0;
@@ -2260,17 +1941,15 @@ static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
2260 int vid_num) 1941 int vid_num)
2261{ 1942{
2262 u32 numbuffers; 1943 u32 numbuffers;
2263 int ret = 0, i, j; 1944 int ret = 0, i;
2264 int image_width, image_height; 1945 struct omapvideo_info *ovid;
2265 struct video_device *vfd;
2266 struct omap_vout_device *vout; 1946 struct omap_vout_device *vout;
2267 int static_vrfb_allocation = 0, vrfb_num_bufs = VRFB_NUM_BUFS;
2268 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); 1947 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2269 struct omap2video_device *vid_dev = 1948 struct omap2video_device *vid_dev =
2270 container_of(v4l2_dev, struct omap2video_device, v4l2_dev); 1949 container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
2271 1950
2272 vout = vid_dev->vouts[vid_num]; 1951 vout = vid_dev->vouts[vid_num];
2273 vfd = vout->vfd; 1952 ovid = &vout->vid_info;
2274 1953
2275 numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers; 1954 numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
2276 vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize; 1955 vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
@@ -2287,66 +1966,16 @@ static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
2287 } 1966 }
2288 } 1967 }
2289 1968
2290 for (i = 0; i < VRFB_NUM_BUFS; i++) {
2291 if (omap_vrfb_request_ctx(&vout->vrfb_context[i])) {
2292 dev_info(&pdev->dev, ": VRFB allocation failed\n");
2293 for (j = 0; j < i; j++)
2294 omap_vrfb_release_ctx(&vout->vrfb_context[j]);
2295 ret = -ENOMEM;
2296 goto free_buffers;
2297 }
2298 }
2299 vout->cropped_offset = 0; 1969 vout->cropped_offset = 0;
2300 1970
2301 /* Calculate VRFB memory size */ 1971 if (ovid->rotation_type == VOUT_ROT_VRFB) {
2302 /* allocate for worst case size */ 1972 int static_vrfb_allocation = (vid_num == 0) ?
2303 image_width = VID_MAX_WIDTH / TILE_SIZE; 1973 vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
2304 if (VID_MAX_WIDTH % TILE_SIZE) 1974 ret = omap_vout_setup_vrfb_bufs(pdev, vid_num,
2305 image_width++; 1975 static_vrfb_allocation);
2306
2307 image_width = image_width * TILE_SIZE;
2308 image_height = VID_MAX_HEIGHT / TILE_SIZE;
2309
2310 if (VID_MAX_HEIGHT % TILE_SIZE)
2311 image_height++;
2312
2313 image_height = image_height * TILE_SIZE;
2314 vout->smsshado_size = PAGE_ALIGN(image_width * image_height * 2 * 2);
2315
2316 /*
2317 * Request and Initialize DMA, for DMA based VRFB transfer
2318 */
2319 vout->vrfb_dma_tx.dev_id = OMAP_DMA_NO_DEVICE;
2320 vout->vrfb_dma_tx.dma_ch = -1;
2321 vout->vrfb_dma_tx.req_status = DMA_CHAN_ALLOTED;
2322 ret = omap_request_dma(vout->vrfb_dma_tx.dev_id, "VRFB DMA TX",
2323 omap_vout_vrfb_dma_tx_callback,
2324 (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch);
2325 if (ret < 0) {
2326 vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
2327 dev_info(&pdev->dev, ": failed to allocate DMA Channel for"
2328 " video%d\n", vfd->minor);
2329 }
2330 init_waitqueue_head(&vout->vrfb_dma_tx.wait);
2331
2332 /* Allocate VRFB buffers if selected through bootargs */
2333 static_vrfb_allocation = (vid_num == 0) ?
2334 vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
2335
2336 /* statically allocated the VRFB buffer is done through
2337 commands line aruments */
2338 if (static_vrfb_allocation) {
2339 if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) {
2340 ret = -ENOMEM;
2341 goto release_vrfb_ctx;
2342 }
2343 vout->vrfb_static_allocation = 1;
2344 } 1976 }
2345 return 0;
2346 1977
2347release_vrfb_ctx: 1978 return ret;
2348 for (j = 0; j < VRFB_NUM_BUFS; j++)
2349 omap_vrfb_release_ctx(&vout->vrfb_context[j]);
2350 1979
2351free_buffers: 1980free_buffers:
2352 for (i = 0; i < numbuffers; i++) { 1981 for (i = 0; i < numbuffers; i++) {
@@ -2389,6 +2018,10 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev)
2389 vout->vid_info.num_overlays = 1; 2018 vout->vid_info.num_overlays = 1;
2390 vout->vid_info.id = k + 1; 2019 vout->vid_info.id = k + 1;
2391 2020
2021 /* Set VRFB as rotation_type for omap2 and omap3 */
2022 if (cpu_is_omap24xx() || cpu_is_omap34xx())
2023 vout->vid_info.rotation_type = VOUT_ROT_VRFB;
2024
2392 /* Setup the default configuration for the video devices 2025 /* Setup the default configuration for the video devices
2393 */ 2026 */
2394 if (omap_vout_setup_video_data(vout) != 0) { 2027 if (omap_vout_setup_video_data(vout) != 0) {
@@ -2422,7 +2055,8 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev)
2422 goto success; 2055 goto success;
2423 2056
2424error2: 2057error2:
2425 omap_vout_release_vrfb(vout); 2058 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
2059 omap_vout_release_vrfb(vout);
2426 omap_vout_free_buffers(vout); 2060 omap_vout_free_buffers(vout);
2427error1: 2061error1:
2428 video_device_release(vfd); 2062 video_device_release(vfd);
@@ -2443,11 +2077,13 @@ success:
2443static void omap_vout_cleanup_device(struct omap_vout_device *vout) 2077static void omap_vout_cleanup_device(struct omap_vout_device *vout)
2444{ 2078{
2445 struct video_device *vfd; 2079 struct video_device *vfd;
2080 struct omapvideo_info *ovid;
2446 2081
2447 if (!vout) 2082 if (!vout)
2448 return; 2083 return;
2449 2084
2450 vfd = vout->vfd; 2085 vfd = vout->vfd;
2086 ovid = &vout->vid_info;
2451 if (vfd) { 2087 if (vfd) {
2452 if (!video_is_registered(vfd)) { 2088 if (!video_is_registered(vfd)) {
2453 /* 2089 /*
@@ -2463,14 +2099,15 @@ static void omap_vout_cleanup_device(struct omap_vout_device *vout)
2463 video_unregister_device(vfd); 2099 video_unregister_device(vfd);
2464 } 2100 }
2465 } 2101 }
2466 2102 if (ovid->rotation_type == VOUT_ROT_VRFB) {
2467 omap_vout_release_vrfb(vout); 2103 omap_vout_release_vrfb(vout);
2104 /* Free the VRFB buffer if allocated
2105 * init time
2106 */
2107 if (vout->vrfb_static_allocation)
2108 omap_vout_free_vrfb_buffers(vout);
2109 }
2468 omap_vout_free_buffers(vout); 2110 omap_vout_free_buffers(vout);
2469 /* Free the VRFB buffer if allocated
2470 * init time
2471 */
2472 if (vout->vrfb_static_allocation)
2473 omap_vout_free_vrfb_buffers(vout);
2474 2111
2475 kfree(vout); 2112 kfree(vout);
2476} 2113}