aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/atmel_lcdfb.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-10-09 16:33:05 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-10-09 16:33:05 -0400
commitc97f68145e8067b3ac4b126a6faebf90f9ffc302 (patch)
treeeb2060681552a00e9efa98224b95f69a3dc84390 /drivers/video/atmel_lcdfb.c
parentb1add0480a95b6ceaece5caf6c50614771eae9b2 (diff)
parent7bff3c4ce44ea48f50dc47a5994454984bd08c59 (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.c84
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
211static 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
224static 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
233static 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
211static void atmel_lcdfb_update_dma(struct fb_info *info, 241static 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