aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Ambrose <martin@ti.com>2010-05-24 17:34:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 11:07:09 -0400
commit1f9c3e1f07e39c8af3bf42236fc553b5bb0f83f1 (patch)
treee7933cec5b2200f3fc0c55b47a7af5bfac558596
parentfb6cb3270af8f2ad3dd556906a9c52aa85754849 (diff)
fbdev: da8xx/omap-l1xx: implement double buffering
This work includes the following: - Implement handler for FBIO_WAITFORVSYNC ioctl. - Allocate the data and palette buffers separately. A consequence of this is that the palette and data loading is now done in different phases. And that the LCD must be disabled temporarily after the palette is loaded but this will only happen once after init and each time the palette is changed. I think this is OK. - Allocate two (ping and pong) framebuffers from memory. - Add pan_display handler which toggles the LCDC DMA registers between the ping and pong buffers. Signed-off-by: Martin Ambrose <martin@ti.com> Cc: Chaithrika U S <chaithrika@ti.com> Cc: Sudhakar Rajashekhara <sudhakar.raj@ti.com> Cc: Krzysztof Helt <krzysztof.h1@poczta.fm> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/video/da8xx-fb.c301
-rw-r--r--include/video/da8xx-fb.h1
2 files changed, 235 insertions, 67 deletions
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 8d244ba0f601..cad7d45c8bac 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -36,7 +36,9 @@
36#define DRIVER_NAME "da8xx_lcdc" 36#define DRIVER_NAME "da8xx_lcdc"
37 37
38/* LCD Status Register */ 38/* LCD Status Register */
39#define LCD_END_OF_FRAME1 BIT(9)
39#define LCD_END_OF_FRAME0 BIT(8) 40#define LCD_END_OF_FRAME0 BIT(8)
41#define LCD_PL_LOAD_DONE BIT(6)
40#define LCD_FIFO_UNDERFLOW BIT(5) 42#define LCD_FIFO_UNDERFLOW BIT(5)
41#define LCD_SYNC_LOST BIT(2) 43#define LCD_SYNC_LOST BIT(2)
42 44
@@ -58,11 +60,13 @@
58#define LCD_PALETTE_LOAD_MODE(x) ((x) << 20) 60#define LCD_PALETTE_LOAD_MODE(x) ((x) << 20)
59#define PALETTE_AND_DATA 0x00 61#define PALETTE_AND_DATA 0x00
60#define PALETTE_ONLY 0x01 62#define PALETTE_ONLY 0x01
63#define DATA_ONLY 0x02
61 64
62#define LCD_MONO_8BIT_MODE BIT(9) 65#define LCD_MONO_8BIT_MODE BIT(9)
63#define LCD_RASTER_ORDER BIT(8) 66#define LCD_RASTER_ORDER BIT(8)
64#define LCD_TFT_MODE BIT(7) 67#define LCD_TFT_MODE BIT(7)
65#define LCD_UNDERFLOW_INT_ENA BIT(6) 68#define LCD_UNDERFLOW_INT_ENA BIT(6)
69#define LCD_PL_ENABLE BIT(4)
66#define LCD_MONOCHROME_MODE BIT(1) 70#define LCD_MONOCHROME_MODE BIT(1)
67#define LCD_RASTER_ENABLE BIT(0) 71#define LCD_RASTER_ENABLE BIT(0)
68#define LCD_TFT_ALT_ENABLE BIT(23) 72#define LCD_TFT_ALT_ENABLE BIT(23)
@@ -87,6 +91,10 @@
87#define LCD_DMA_CTRL_REG 0x40 91#define LCD_DMA_CTRL_REG 0x40
88#define LCD_DMA_FRM_BUF_BASE_ADDR_0_REG 0x44 92#define LCD_DMA_FRM_BUF_BASE_ADDR_0_REG 0x44
89#define LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG 0x48 93#define LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG 0x48
94#define LCD_DMA_FRM_BUF_BASE_ADDR_1_REG 0x4C
95#define LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG 0x50
96
97#define LCD_NUM_BUFFERS 2
90 98
91#define WSI_TIMEOUT 50 99#define WSI_TIMEOUT 50
92#define PALETTE_SIZE 256 100#define PALETTE_SIZE 256
@@ -111,13 +119,20 @@ static inline void lcdc_write(unsigned int val, unsigned int addr)
111struct da8xx_fb_par { 119struct da8xx_fb_par {
112 resource_size_t p_palette_base; 120 resource_size_t p_palette_base;
113 unsigned char *v_palette_base; 121 unsigned char *v_palette_base;
122 dma_addr_t vram_phys;
123 unsigned long vram_size;
124 void *vram_virt;
125 unsigned int dma_start;
126 unsigned int dma_end;
114 struct clk *lcdc_clk; 127 struct clk *lcdc_clk;
115 int irq; 128 int irq;
116 unsigned short pseudo_palette[16]; 129 unsigned short pseudo_palette[16];
117 unsigned int databuf_sz;
118 unsigned int palette_sz; 130 unsigned int palette_sz;
119 unsigned int pxl_clk; 131 unsigned int pxl_clk;
120 int blank; 132 int blank;
133 wait_queue_head_t vsync_wait;
134 int vsync_flag;
135 int vsync_timeout;
121#ifdef CONFIG_CPU_FREQ 136#ifdef CONFIG_CPU_FREQ
122 struct notifier_block freq_transition; 137 struct notifier_block freq_transition;
123#endif 138#endif
@@ -148,9 +163,9 @@ static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = {
148 .type = FB_TYPE_PACKED_PIXELS, 163 .type = FB_TYPE_PACKED_PIXELS,
149 .type_aux = 0, 164 .type_aux = 0,
150 .visual = FB_VISUAL_PSEUDOCOLOR, 165 .visual = FB_VISUAL_PSEUDOCOLOR,
151 .xpanstep = 1, 166 .xpanstep = 0,
152 .ypanstep = 1, 167 .ypanstep = 1,
153 .ywrapstep = 1, 168 .ywrapstep = 0,
154 .accel = FB_ACCEL_NONE 169 .accel = FB_ACCEL_NONE
155}; 170};
156 171
@@ -221,22 +236,48 @@ static inline void lcd_disable_raster(void)
221 236
222static void lcd_blit(int load_mode, struct da8xx_fb_par *par) 237static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
223{ 238{
224 u32 tmp = par->p_palette_base + par->databuf_sz - 4; 239 u32 start;
225 u32 reg; 240 u32 end;
241 u32 reg_ras;
242 u32 reg_dma;
243
244 /* init reg to clear PLM (loading mode) fields */
245 reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
246 reg_ras &= ~(3 << 20);
247
248 reg_dma = lcdc_read(LCD_DMA_CTRL_REG);
249
250 if (load_mode == LOAD_DATA) {
251 start = par->dma_start;
252 end = par->dma_end;
253
254 reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
255 reg_dma |= LCD_END_OF_FRAME_INT_ENA;
256 reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
257
258 lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
259 lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
260 lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
261 lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
262 } else if (load_mode == LOAD_PALETTE) {
263 start = par->p_palette_base;
264 end = start + par->palette_sz - 1;
265
266 reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
267 reg_ras |= LCD_PL_ENABLE;
268
269 lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
270 lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
271 }
226 272
227 /* Update the databuf in the hw. */ 273 lcdc_write(reg_dma, LCD_DMA_CTRL_REG);
228 lcdc_write(par->p_palette_base, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); 274 lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
229 lcdc_write(tmp, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
230 275
231 /* Start the DMA. */ 276 /*
232 reg = lcdc_read(LCD_RASTER_CTRL_REG); 277 * The Raster enable bit must be set after all other control fields are
233 reg &= ~(3 << 20); 278 * set.
234 if (load_mode == LOAD_DATA) 279 */
235 reg |= LCD_PALETTE_LOAD_MODE(PALETTE_AND_DATA); 280 lcd_enable_raster();
236 else if (load_mode == LOAD_PALETTE)
237 reg |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
238
239 lcdc_write(reg, LCD_RASTER_CTRL_REG);
240} 281}
241 282
242/* Configure the Burst Size of DMA */ 283/* Configure the Burst Size of DMA */
@@ -368,12 +409,8 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
368static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, 409static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
369 u32 bpp, u32 raster_order) 410 u32 bpp, u32 raster_order)
370{ 411{
371 u32 bpl, reg; 412 u32 reg;
372 413
373 /* Disable Dual Frame Buffer. */
374 reg = lcdc_read(LCD_DMA_CTRL_REG);
375 lcdc_write(reg & ~LCD_DUAL_FRAME_BUFFER_ENABLE,
376 LCD_DMA_CTRL_REG);
377 /* Set the Panel Width */ 414 /* Set the Panel Width */
378 /* Pixels per line = (PPL + 1)*16 */ 415 /* Pixels per line = (PPL + 1)*16 */
379 /*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/ 416 /*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/
@@ -410,9 +447,6 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
410 return -EINVAL; 447 return -EINVAL;
411 } 448 }
412 449
413 bpl = width * bpp / 8;
414 par->databuf_sz = height * bpl + par->palette_sz;
415
416 return 0; 450 return 0;
417} 451}
418 452
@@ -421,8 +455,9 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
421 struct fb_info *info) 455 struct fb_info *info)
422{ 456{
423 struct da8xx_fb_par *par = info->par; 457 struct da8xx_fb_par *par = info->par;
424 unsigned short *palette = (unsigned short *)par->v_palette_base; 458 unsigned short *palette = (unsigned short *) par->v_palette_base;
425 u_short pal; 459 u_short pal;
460 int update_hw = 0;
426 461
427 if (regno > 255) 462 if (regno > 255)
428 return 1; 463 return 1;
@@ -439,8 +474,10 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
439 pal |= (green & 0x00f0); 474 pal |= (green & 0x00f0);
440 pal |= (blue & 0x000f); 475 pal |= (blue & 0x000f);
441 476
442 palette[regno] = pal; 477 if (palette[regno] != pal) {
443 478 update_hw = 1;
479 palette[regno] = pal;
480 }
444 } else if ((info->var.bits_per_pixel == 16) && regno < 16) { 481 } else if ((info->var.bits_per_pixel == 16) && regno < 16) {
445 red >>= (16 - info->var.red.length); 482 red >>= (16 - info->var.red.length);
446 red <<= info->var.red.offset; 483 red <<= info->var.red.offset;
@@ -453,9 +490,16 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
453 490
454 par->pseudo_palette[regno] = red | green | blue; 491 par->pseudo_palette[regno] = red | green | blue;
455 492
456 palette[0] = 0x4000; 493 if (palette[0] != 0x4000) {
494 update_hw = 1;
495 palette[0] = 0x4000;
496 }
457 } 497 }
458 498
499 /* Update the palette in the h/w as needed. */
500 if (update_hw)
501 lcd_blit(LOAD_PALETTE, par);
502
459 return 0; 503 return 0;
460} 504}
461 505
@@ -541,15 +585,54 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
541 585
542static irqreturn_t lcdc_irq_handler(int irq, void *arg) 586static irqreturn_t lcdc_irq_handler(int irq, void *arg)
543{ 587{
588 struct da8xx_fb_par *par = arg;
544 u32 stat = lcdc_read(LCD_STAT_REG); 589 u32 stat = lcdc_read(LCD_STAT_REG);
590 u32 reg_ras;
545 591
546 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { 592 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
547 lcd_disable_raster(); 593 lcd_disable_raster();
548 lcdc_write(stat, LCD_STAT_REG); 594 lcdc_write(stat, LCD_STAT_REG);
549 lcd_enable_raster(); 595 lcd_enable_raster();
550 } else 596 } else if (stat & LCD_PL_LOAD_DONE) {
597 /*
598 * Must disable raster before changing state of any control bit.
599 * And also must be disabled before clearing the PL loading
600 * interrupt via the following write to the status register. If
601 * this is done after then one gets multiple PL done interrupts.
602 */
603 lcd_disable_raster();
604
551 lcdc_write(stat, LCD_STAT_REG); 605 lcdc_write(stat, LCD_STAT_REG);
552 606
607 /* Disable PL completion inerrupt */
608 reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
609 reg_ras &= ~LCD_PL_ENABLE;
610 lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
611
612 /* Setup and start data loading mode */
613 lcd_blit(LOAD_DATA, par);
614 } else {
615 lcdc_write(stat, LCD_STAT_REG);
616
617 if (stat & LCD_END_OF_FRAME0) {
618 lcdc_write(par->dma_start,
619 LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
620 lcdc_write(par->dma_end,
621 LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
622 par->vsync_flag = 1;
623 wake_up_interruptible(&par->vsync_wait);
624 }
625
626 if (stat & LCD_END_OF_FRAME1) {
627 lcdc_write(par->dma_start,
628 LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
629 lcdc_write(par->dma_end,
630 LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
631 par->vsync_flag = 1;
632 wake_up_interruptible(&par->vsync_wait);
633 }
634 }
635
553 return IRQ_HANDLED; 636 return IRQ_HANDLED;
554} 637}
555 638
@@ -654,9 +737,10 @@ static int __devexit fb_remove(struct platform_device *dev)
654 737
655 unregister_framebuffer(info); 738 unregister_framebuffer(info);
656 fb_dealloc_cmap(&info->cmap); 739 fb_dealloc_cmap(&info->cmap);
657 dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE, 740 dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
658 info->screen_base - PAGE_SIZE, 741 par->p_palette_base);
659 info->fix.smem_start); 742 dma_free_coherent(NULL, par->vram_size, par->vram_virt,
743 par->vram_phys);
660 free_irq(par->irq, par); 744 free_irq(par->irq, par);
661 clk_disable(par->lcdc_clk); 745 clk_disable(par->lcdc_clk);
662 clk_put(par->lcdc_clk); 746 clk_put(par->lcdc_clk);
@@ -668,6 +752,39 @@ static int __devexit fb_remove(struct platform_device *dev)
668 return 0; 752 return 0;
669} 753}
670 754
755/*
756 * Function to wait for vertical sync which for this LCD peripheral
757 * translates into waiting for the current raster frame to complete.
758 */
759static int fb_wait_for_vsync(struct fb_info *info)
760{
761 struct da8xx_fb_par *par = info->par;
762 int ret;
763
764 /*
765 * Set flag to 0 and wait for isr to set to 1. It would seem there is a
766 * race condition here where the ISR could have occured just before or
767 * just after this set. But since we are just coarsely waiting for
768 * a frame to complete then that's OK. i.e. if the frame completed
769 * just before this code executed then we have to wait another full
770 * frame time but there is no way to avoid such a situation. On the
771 * other hand if the frame completed just after then we don't need
772 * to wait long at all. Either way we are guaranteed to return to the
773 * user immediately after a frame completion which is all that is
774 * required.
775 */
776 par->vsync_flag = 0;
777 ret = wait_event_interruptible_timeout(par->vsync_wait,
778 par->vsync_flag != 0,
779 par->vsync_timeout);
780 if (ret < 0)
781 return ret;
782 if (ret == 0)
783 return -ETIMEDOUT;
784
785 return 0;
786}
787
671static int fb_ioctl(struct fb_info *info, unsigned int cmd, 788static int fb_ioctl(struct fb_info *info, unsigned int cmd,
672 unsigned long arg) 789 unsigned long arg)
673{ 790{
@@ -697,6 +814,8 @@ static int fb_ioctl(struct fb_info *info, unsigned int cmd,
697 sync_arg.pulse_width, 814 sync_arg.pulse_width,
698 sync_arg.front_porch); 815 sync_arg.front_porch);
699 break; 816 break;
817 case FBIO_WAITFORVSYNC:
818 return fb_wait_for_vsync(info);
700 default: 819 default:
701 return -EINVAL; 820 return -EINVAL;
702 } 821 }
@@ -732,10 +851,47 @@ static int cfb_blank(int blank, struct fb_info *info)
732 return ret; 851 return ret;
733} 852}
734 853
854/*
855 * Set new x,y offsets in the virtual display for the visible area and switch
856 * to the new mode.
857 */
858static int da8xx_pan_display(struct fb_var_screeninfo *var,
859 struct fb_info *fbi)
860{
861 int ret = 0;
862 struct fb_var_screeninfo new_var;
863 struct da8xx_fb_par *par = fbi->par;
864 struct fb_fix_screeninfo *fix = &fbi->fix;
865 unsigned int end;
866 unsigned int start;
867
868 if (var->xoffset != fbi->var.xoffset ||
869 var->yoffset != fbi->var.yoffset) {
870 memcpy(&new_var, &fbi->var, sizeof(new_var));
871 new_var.xoffset = var->xoffset;
872 new_var.yoffset = var->yoffset;
873 if (fb_check_var(&new_var, fbi))
874 ret = -EINVAL;
875 else {
876 memcpy(&fbi->var, &new_var, sizeof(new_var));
877
878 start = fix->smem_start +
879 new_var.yoffset * fix->line_length +
880 new_var.xoffset * var->bits_per_pixel / 8;
881 end = start + var->yres * fix->line_length - 1;
882 par->dma_start = start;
883 par->dma_end = end;
884 }
885 }
886
887 return ret;
888}
889
735static struct fb_ops da8xx_fb_ops = { 890static struct fb_ops da8xx_fb_ops = {
736 .owner = THIS_MODULE, 891 .owner = THIS_MODULE,
737 .fb_check_var = fb_check_var, 892 .fb_check_var = fb_check_var,
738 .fb_setcolreg = fb_setcolreg, 893 .fb_setcolreg = fb_setcolreg,
894 .fb_pan_display = da8xx_pan_display,
739 .fb_ioctl = fb_ioctl, 895 .fb_ioctl = fb_ioctl,
740 .fb_fillrect = cfb_fillrect, 896 .fb_fillrect = cfb_fillrect,
741 .fb_copyarea = cfb_copyarea, 897 .fb_copyarea = cfb_copyarea,
@@ -829,40 +985,53 @@ static int __init fb_probe(struct platform_device *device)
829 } 985 }
830 986
831 /* allocate frame buffer */ 987 /* allocate frame buffer */
832 da8xx_fb_info->screen_base = dma_alloc_coherent(NULL, 988 par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp;
833 par->databuf_sz + PAGE_SIZE, 989 par->vram_size = PAGE_ALIGN(par->vram_size/8);
834 (resource_size_t *) 990 par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
835 &da8xx_fb_info->fix.smem_start, 991
836 GFP_KERNEL | GFP_DMA); 992 par->vram_virt = dma_alloc_coherent(NULL,
837 993 par->vram_size,
838 if (!da8xx_fb_info->screen_base) { 994 (resource_size_t *) &par->vram_phys,
995 GFP_KERNEL | GFP_DMA);
996 if (!par->vram_virt) {
839 dev_err(&device->dev, 997 dev_err(&device->dev,
840 "GLCD: kmalloc for frame buffer failed\n"); 998 "GLCD: kmalloc for frame buffer failed\n");
841 ret = -EINVAL; 999 ret = -EINVAL;
842 goto err_release_fb; 1000 goto err_release_fb;
843 } 1001 }
844 1002
845 /* move palette base pointer by (PAGE_SIZE - palette_sz) bytes */ 1003 da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt;
846 par->v_palette_base = da8xx_fb_info->screen_base + 1004 da8xx_fb_fix.smem_start = par->vram_phys;
847 (PAGE_SIZE - par->palette_sz); 1005 da8xx_fb_fix.smem_len = par->vram_size;
848 par->p_palette_base = da8xx_fb_info->fix.smem_start + 1006 da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8;
849 (PAGE_SIZE - par->palette_sz); 1007
850 1008 par->dma_start = par->vram_phys;
851 /* the rest of the frame buffer is pixel data */ 1009 par->dma_end = par->dma_start + lcdc_info->height *
852 da8xx_fb_info->screen_base = par->v_palette_base + par->palette_sz; 1010 da8xx_fb_fix.line_length - 1;
853 da8xx_fb_fix.smem_start = par->p_palette_base + par->palette_sz; 1011
854 da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz; 1012 /* allocate palette buffer */
855 da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; 1013 par->v_palette_base = dma_alloc_coherent(NULL,
1014 PALETTE_SIZE,
1015 (resource_size_t *)
1016 &par->p_palette_base,
1017 GFP_KERNEL | GFP_DMA);
1018 if (!par->v_palette_base) {
1019 dev_err(&device->dev,
1020 "GLCD: kmalloc for palette buffer failed\n");
1021 ret = -EINVAL;
1022 goto err_release_fb_mem;
1023 }
1024 memset(par->v_palette_base, 0, PALETTE_SIZE);
856 1025
857 par->irq = platform_get_irq(device, 0); 1026 par->irq = platform_get_irq(device, 0);
858 if (par->irq < 0) { 1027 if (par->irq < 0) {
859 ret = -ENOENT; 1028 ret = -ENOENT;
860 goto err_release_fb_mem; 1029 goto err_release_pl_mem;
861 } 1030 }
862 1031
863 ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par); 1032 ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
864 if (ret) 1033 if (ret)
865 goto err_release_fb_mem; 1034 goto err_release_pl_mem;
866 1035
867 /* Initialize par */ 1036 /* Initialize par */
868 da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp; 1037 da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
@@ -870,8 +1039,8 @@ static int __init fb_probe(struct platform_device *device)
870 da8xx_fb_var.xres = lcdc_info->width; 1039 da8xx_fb_var.xres = lcdc_info->width;
871 da8xx_fb_var.xres_virtual = lcdc_info->width; 1040 da8xx_fb_var.xres_virtual = lcdc_info->width;
872 1041
873 da8xx_fb_var.yres = lcdc_info->height; 1042 da8xx_fb_var.yres = lcdc_info->height;
874 da8xx_fb_var.yres_virtual = lcdc_info->height; 1043 da8xx_fb_var.yres_virtual = lcdc_info->height * LCD_NUM_BUFFERS;
875 1044
876 da8xx_fb_var.grayscale = 1045 da8xx_fb_var.grayscale =
877 lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0; 1046 lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0;
@@ -892,18 +1061,18 @@ static int __init fb_probe(struct platform_device *device)
892 ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0); 1061 ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
893 if (ret) 1062 if (ret)
894 goto err_free_irq; 1063 goto err_free_irq;
895
896 /* First palette_sz byte of the frame buffer is the palette */
897 da8xx_fb_info->cmap.len = par->palette_sz; 1064 da8xx_fb_info->cmap.len = par->palette_sz;
898 1065
899 /* Flush the buffer to the screen. */
900 lcd_blit(LOAD_DATA, par);
901
902 /* initialize var_screeninfo */ 1066 /* initialize var_screeninfo */
903 da8xx_fb_var.activate = FB_ACTIVATE_FORCE; 1067 da8xx_fb_var.activate = FB_ACTIVATE_FORCE;
904 fb_set_var(da8xx_fb_info, &da8xx_fb_var); 1068 fb_set_var(da8xx_fb_info, &da8xx_fb_var);
905 1069
906 dev_set_drvdata(&device->dev, da8xx_fb_info); 1070 dev_set_drvdata(&device->dev, da8xx_fb_info);
1071
1072 /* initialize the vsync wait queue */
1073 init_waitqueue_head(&par->vsync_wait);
1074 par->vsync_timeout = HZ / 5;
1075
907 /* Register the Frame Buffer */ 1076 /* Register the Frame Buffer */
908 if (register_framebuffer(da8xx_fb_info) < 0) { 1077 if (register_framebuffer(da8xx_fb_info) < 0) {
909 dev_err(&device->dev, 1078 dev_err(&device->dev,
@@ -919,10 +1088,6 @@ static int __init fb_probe(struct platform_device *device)
919 goto err_cpu_freq; 1088 goto err_cpu_freq;
920 } 1089 }
921#endif 1090#endif
922
923 /* enable raster engine */
924 lcd_enable_raster();
925
926 return 0; 1091 return 0;
927 1092
928#ifdef CONFIG_CPU_FREQ 1093#ifdef CONFIG_CPU_FREQ
@@ -936,10 +1101,12 @@ err_dealloc_cmap:
936err_free_irq: 1101err_free_irq:
937 free_irq(par->irq, par); 1102 free_irq(par->irq, par);
938 1103
1104err_release_pl_mem:
1105 dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
1106 par->p_palette_base);
1107
939err_release_fb_mem: 1108err_release_fb_mem:
940 dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE, 1109 dma_free_coherent(NULL, par->vram_size, par->vram_virt, par->vram_phys);
941 da8xx_fb_info->screen_base - PAGE_SIZE,
942 da8xx_fb_info->fix.smem_start);
943 1110
944err_release_fb: 1111err_release_fb:
945 framebuffer_release(da8xx_fb_info); 1112 framebuffer_release(da8xx_fb_info);
diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h
index 89d43b3d4cb9..6316cdabf73f 100644
--- a/include/video/da8xx-fb.h
+++ b/include/video/da8xx-fb.h
@@ -99,6 +99,7 @@ struct lcd_sync_arg {
99#define FBIPUT_COLOR _IOW('F', 6, int) 99#define FBIPUT_COLOR _IOW('F', 6, int)
100#define FBIPUT_HSYNC _IOW('F', 9, int) 100#define FBIPUT_HSYNC _IOW('F', 9, int)
101#define FBIPUT_VSYNC _IOW('F', 10, int) 101#define FBIPUT_VSYNC _IOW('F', 10, int)
102#define FBIO_WAITFORVSYNC _IOW('F', 0x20, u_int32_t)
102 103
103#endif /* ifndef DA8XX_FB_H */ 104#endif /* ifndef DA8XX_FB_H */
104 105