aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/atmel_lcdfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/atmel_lcdfb.c')
-rw-r--r--drivers/video/atmel_lcdfb.c74
1 files changed, 65 insertions, 9 deletions
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index fc65c02306dd..8ffdf3578768 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -31,7 +31,8 @@
31#define ATMEL_LCDC_CVAL_DEFAULT 0xc8 31#define ATMEL_LCDC_CVAL_DEFAULT 0xc8
32#define ATMEL_LCDC_DMA_BURST_LEN 8 32#define ATMEL_LCDC_DMA_BURST_LEN 8
33 33
34#if defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9) 34#if defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9) || \
35 defined(CONFIG_ARCH_AT91SAM9RL)
35#define ATMEL_LCDC_FIFO_SIZE 2048 36#define ATMEL_LCDC_FIFO_SIZE 2048
36#else 37#else
37#define ATMEL_LCDC_FIFO_SIZE 512 38#define ATMEL_LCDC_FIFO_SIZE 512
@@ -250,6 +251,8 @@ static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo)
250 return -ENOMEM; 251 return -ENOMEM;
251 } 252 }
252 253
254 memset(info->screen_base, 0, info->fix.smem_len);
255
253 return 0; 256 return 0;
254} 257}
255 258
@@ -336,19 +339,35 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
336 break; 339 break;
337 case 15: 340 case 15:
338 case 16: 341 case 16:
339 var->red.offset = 0; 342 if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
343 /* RGB:565 mode */
344 var->red.offset = 11;
345 var->blue.offset = 0;
346 var->green.length = 6;
347 } else {
348 /* BGR:555 mode */
349 var->red.offset = 0;
350 var->blue.offset = 10;
351 var->green.length = 5;
352 }
340 var->green.offset = 5; 353 var->green.offset = 5;
341 var->blue.offset = 10; 354 var->red.length = var->blue.length = 5;
342 var->red.length = var->green.length = var->blue.length = 5;
343 break; 355 break;
344 case 32: 356 case 32:
345 var->transp.offset = 24; 357 var->transp.offset = 24;
346 var->transp.length = 8; 358 var->transp.length = 8;
347 /* fall through */ 359 /* fall through */
348 case 24: 360 case 24:
349 var->red.offset = 0; 361 if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
362 /* RGB:888 mode */
363 var->red.offset = 16;
364 var->blue.offset = 0;
365 } else {
366 /* BGR:888 mode */
367 var->red.offset = 0;
368 var->blue.offset = 16;
369 }
350 var->green.offset = 8; 370 var->green.offset = 8;
351 var->blue.offset = 16;
352 var->red.length = var->green.length = var->blue.length = 8; 371 var->red.length = var->green.length = var->blue.length = 8;
353 break; 372 break;
354 default: 373 default:
@@ -634,7 +653,6 @@ static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo)
634 struct fb_info *info = sinfo->info; 653 struct fb_info *info = sinfo->info;
635 int ret = 0; 654 int ret = 0;
636 655
637 memset_io(info->screen_base, 0, info->fix.smem_len);
638 info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW; 656 info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
639 657
640 dev_info(info->device, 658 dev_info(info->device,
@@ -696,6 +714,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
696 sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control; 714 sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control;
697 sinfo->guard_time = pdata_sinfo->guard_time; 715 sinfo->guard_time = pdata_sinfo->guard_time;
698 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight; 716 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
717 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
699 } else { 718 } else {
700 dev_err(dev, "cannot get default configuration\n"); 719 dev_err(dev, "cannot get default configuration\n");
701 goto free_info; 720 goto free_info;
@@ -764,6 +783,11 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
764 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); 783 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
765 if (!info->screen_base) 784 if (!info->screen_base)
766 goto release_intmem; 785 goto release_intmem;
786
787 /*
788 * Don't clear the framebuffer -- someone may have set
789 * up a splash image.
790 */
767 } else { 791 } else {
768 /* alocate memory buffer */ 792 /* alocate memory buffer */
769 ret = atmel_lcdfb_alloc_video_memory(sinfo); 793 ret = atmel_lcdfb_alloc_video_memory(sinfo);
@@ -903,10 +927,42 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
903 return 0; 927 return 0;
904} 928}
905 929
930#ifdef CONFIG_PM
931
932static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg)
933{
934 struct fb_info *info = platform_get_drvdata(pdev);
935 struct atmel_lcdfb_info *sinfo = info->par;
936
937 sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
938 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
939 if (sinfo->atmel_lcdfb_power_control)
940 sinfo->atmel_lcdfb_power_control(0);
941 atmel_lcdfb_stop_clock(sinfo);
942 return 0;
943}
944
945static int atmel_lcdfb_resume(struct platform_device *pdev)
946{
947 struct fb_info *info = platform_get_drvdata(pdev);
948 struct atmel_lcdfb_info *sinfo = info->par;
949
950 atmel_lcdfb_start_clock(sinfo);
951 if (sinfo->atmel_lcdfb_power_control)
952 sinfo->atmel_lcdfb_power_control(1);
953 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon);
954 return 0;
955}
956
957#else
958#define atmel_lcdfb_suspend NULL
959#define atmel_lcdfb_resume NULL
960#endif
961
906static struct platform_driver atmel_lcdfb_driver = { 962static struct platform_driver atmel_lcdfb_driver = {
907 .remove = __exit_p(atmel_lcdfb_remove), 963 .remove = __exit_p(atmel_lcdfb_remove),
908 964 .suspend = atmel_lcdfb_suspend,
909// FIXME need suspend, resume 965 .resume = atmel_lcdfb_resume,
910 966
911 .driver = { 967 .driver = {
912 .name = "atmel_lcdfb", 968 .name = "atmel_lcdfb",