diff options
Diffstat (limited to 'drivers/video/atmel_lcdfb.c')
-rw-r--r-- | drivers/video/atmel_lcdfb.c | 74 |
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 | |||
932 | static 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 | |||
945 | static 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 | |||
906 | static struct platform_driver atmel_lcdfb_driver = { | 962 | static 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", |