aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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