diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-10-09 16:33:05 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-10-09 16:33:05 -0400 |
commit | c97f68145e8067b3ac4b126a6faebf90f9ffc302 (patch) | |
tree | eb2060681552a00e9efa98224b95f69a3dc84390 /drivers/video/atmel_lcdfb.c | |
parent | b1add0480a95b6ceaece5caf6c50614771eae9b2 (diff) | |
parent | 7bff3c4ce44ea48f50dc47a5994454984bd08c59 (diff) |
Merge branch 'for-rmk' of git://source.mvista.com/git/linux-davinci-2.6.git
Merge branch 'davinci' into devel
Diffstat (limited to 'drivers/video/atmel_lcdfb.c')
-rw-r--r-- | drivers/video/atmel_lcdfb.c | 84 |
1 files changed, 49 insertions, 35 deletions
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index cedfd01c9833..d38fd5217422 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -208,6 +208,36 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) | |||
208 | return value; | 208 | return value; |
209 | } | 209 | } |
210 | 210 | ||
211 | static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo) | ||
212 | { | ||
213 | /* Turn off the LCD controller and the DMA controller */ | ||
214 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, | ||
215 | sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); | ||
216 | |||
217 | /* Wait for the LCDC core to become idle */ | ||
218 | while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) | ||
219 | msleep(10); | ||
220 | |||
221 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); | ||
222 | } | ||
223 | |||
224 | static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo) | ||
225 | { | ||
226 | atmel_lcdfb_stop_nowait(sinfo); | ||
227 | |||
228 | /* Wait for DMA engine to become idle... */ | ||
229 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) | ||
230 | msleep(10); | ||
231 | } | ||
232 | |||
233 | static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo) | ||
234 | { | ||
235 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); | ||
236 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, | ||
237 | (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ||
238 | | ATMEL_LCDC_PWR); | ||
239 | } | ||
240 | |||
211 | static void atmel_lcdfb_update_dma(struct fb_info *info, | 241 | static void atmel_lcdfb_update_dma(struct fb_info *info, |
212 | struct fb_var_screeninfo *var) | 242 | struct fb_var_screeninfo *var) |
213 | { | 243 | { |
@@ -424,26 +454,8 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo) | |||
424 | { | 454 | { |
425 | might_sleep(); | 455 | might_sleep(); |
426 | 456 | ||
427 | /* LCD power off */ | 457 | atmel_lcdfb_stop(sinfo); |
428 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); | 458 | atmel_lcdfb_start(sinfo); |
429 | |||
430 | /* wait for the LCDC core to become idle */ | ||
431 | while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) | ||
432 | msleep(10); | ||
433 | |||
434 | /* DMA disable */ | ||
435 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); | ||
436 | |||
437 | /* wait for DMA engine to become idle */ | ||
438 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) | ||
439 | msleep(10); | ||
440 | |||
441 | /* LCD power on */ | ||
442 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, | ||
443 | (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); | ||
444 | |||
445 | /* DMA enable */ | ||
446 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); | ||
447 | } | 459 | } |
448 | 460 | ||
449 | /** | 461 | /** |
@@ -475,14 +487,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) | |||
475 | info->var.xres, info->var.yres, | 487 | info->var.xres, info->var.yres, |
476 | info->var.xres_virtual, info->var.yres_virtual); | 488 | info->var.xres_virtual, info->var.yres_virtual); |
477 | 489 | ||
478 | /* Turn off the LCD controller and the DMA controller */ | 490 | atmel_lcdfb_stop_nowait(sinfo); |
479 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); | ||
480 | |||
481 | /* Wait for the LCDC core to become idle */ | ||
482 | while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) | ||
483 | msleep(10); | ||
484 | |||
485 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); | ||
486 | 491 | ||
487 | if (info->var.bits_per_pixel == 1) | 492 | if (info->var.bits_per_pixel == 1) |
488 | info->fix.visual = FB_VISUAL_MONO01; | 493 | info->fix.visual = FB_VISUAL_MONO01; |
@@ -587,13 +592,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) | |||
587 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) | 592 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) |
588 | msleep(10); | 593 | msleep(10); |
589 | 594 | ||
590 | dev_dbg(info->device, " * re-enable DMA engine\n"); | 595 | atmel_lcdfb_start(sinfo); |
591 | /* ...and enable it with updated configuration */ | ||
592 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); | ||
593 | |||
594 | dev_dbg(info->device, " * re-enable LCDC core\n"); | ||
595 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, | ||
596 | (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); | ||
597 | 596 | ||
598 | dev_dbg(info->device, " * DONE\n"); | 597 | dev_dbg(info->device, " * DONE\n"); |
599 | 598 | ||
@@ -1036,11 +1035,20 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
1036 | struct fb_info *info = platform_get_drvdata(pdev); | 1035 | struct fb_info *info = platform_get_drvdata(pdev); |
1037 | struct atmel_lcdfb_info *sinfo = info->par; | 1036 | struct atmel_lcdfb_info *sinfo = info->par; |
1038 | 1037 | ||
1038 | /* | ||
1039 | * We don't want to handle interrupts while the clock is | ||
1040 | * stopped. It may take forever. | ||
1041 | */ | ||
1042 | lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); | ||
1043 | |||
1039 | sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); | 1044 | sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); |
1040 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0); | 1045 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0); |
1041 | if (sinfo->atmel_lcdfb_power_control) | 1046 | if (sinfo->atmel_lcdfb_power_control) |
1042 | sinfo->atmel_lcdfb_power_control(0); | 1047 | sinfo->atmel_lcdfb_power_control(0); |
1048 | |||
1049 | atmel_lcdfb_stop(sinfo); | ||
1043 | atmel_lcdfb_stop_clock(sinfo); | 1050 | atmel_lcdfb_stop_clock(sinfo); |
1051 | |||
1044 | return 0; | 1052 | return 0; |
1045 | } | 1053 | } |
1046 | 1054 | ||
@@ -1050,9 +1058,15 @@ static int atmel_lcdfb_resume(struct platform_device *pdev) | |||
1050 | struct atmel_lcdfb_info *sinfo = info->par; | 1058 | struct atmel_lcdfb_info *sinfo = info->par; |
1051 | 1059 | ||
1052 | atmel_lcdfb_start_clock(sinfo); | 1060 | atmel_lcdfb_start_clock(sinfo); |
1061 | atmel_lcdfb_start(sinfo); | ||
1053 | if (sinfo->atmel_lcdfb_power_control) | 1062 | if (sinfo->atmel_lcdfb_power_control) |
1054 | sinfo->atmel_lcdfb_power_control(1); | 1063 | sinfo->atmel_lcdfb_power_control(1); |
1055 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon); | 1064 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon); |
1065 | |||
1066 | /* Enable FIFO & DMA errors */ | ||
1067 | lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ||
1068 | | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI); | ||
1069 | |||
1056 | return 0; | 1070 | return 0; |
1057 | } | 1071 | } |
1058 | 1072 | ||