aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbdev/au1100fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/au1100fb.c')
-rw-r--r--drivers/video/fbdev/au1100fb.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c
index 372d4aea9d1c..0676746ec68c 100644
--- a/drivers/video/fbdev/au1100fb.c
+++ b/drivers/video/fbdev/au1100fb.c
@@ -41,6 +41,7 @@
41 * with this program; if not, write to the Free Software Foundation, Inc., 41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 675 Mass Ave, Cambridge, MA 02139, USA. 42 * 675 Mass Ave, Cambridge, MA 02139, USA.
43 */ 43 */
44#include <linux/clk.h>
44#include <linux/module.h> 45#include <linux/module.h>
45#include <linux/kernel.h> 46#include <linux/kernel.h>
46#include <linux/errno.h> 47#include <linux/errno.h>
@@ -113,7 +114,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
113 case VESA_NO_BLANKING: 114 case VESA_NO_BLANKING:
114 /* Turn on panel */ 115 /* Turn on panel */
115 fbdev->regs->lcd_control |= LCD_CONTROL_GO; 116 fbdev->regs->lcd_control |= LCD_CONTROL_GO;
116 au_sync(); 117 wmb(); /* drain writebuffer */
117 break; 118 break;
118 119
119 case VESA_VSYNC_SUSPEND: 120 case VESA_VSYNC_SUSPEND:
@@ -121,7 +122,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
121 case VESA_POWERDOWN: 122 case VESA_POWERDOWN:
122 /* Turn off panel */ 123 /* Turn off panel */
123 fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; 124 fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
124 au_sync(); 125 wmb(); /* drain writebuffer */
125 break; 126 break;
126 default: 127 default:
127 break; 128 break;
@@ -434,7 +435,7 @@ static int au1100fb_drv_probe(struct platform_device *dev)
434 struct au1100fb_device *fbdev = NULL; 435 struct au1100fb_device *fbdev = NULL;
435 struct resource *regs_res; 436 struct resource *regs_res;
436 unsigned long page; 437 unsigned long page;
437 u32 sys_clksrc; 438 struct clk *c;
438 439
439 /* Allocate new device private */ 440 /* Allocate new device private */
440 fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device), 441 fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device),
@@ -473,6 +474,13 @@ static int au1100fb_drv_probe(struct platform_device *dev)
473 print_dbg("Register memory map at %p", fbdev->regs); 474 print_dbg("Register memory map at %p", fbdev->regs);
474 print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len); 475 print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len);
475 476
477 c = clk_get(NULL, "lcd_intclk");
478 if (!IS_ERR(c)) {
479 fbdev->lcdclk = c;
480 clk_set_rate(c, 48000000);
481 clk_prepare_enable(c);
482 }
483
476 /* Allocate the framebuffer to the maximum screen size * nbr of video buffers */ 484 /* Allocate the framebuffer to the maximum screen size * nbr of video buffers */
477 fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * 485 fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
478 (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; 486 (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
@@ -506,10 +514,6 @@ static int au1100fb_drv_probe(struct platform_device *dev)
506 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); 514 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
507 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); 515 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
508 516
509 /* Setup LCD clock to AUX (48 MHz) */
510 sys_clksrc = au_readl(SYS_CLKSRC) & ~(SYS_CS_ML_MASK | SYS_CS_DL | SYS_CS_CL);
511 au_writel((sys_clksrc | (1 << SYS_CS_ML_BIT)), SYS_CLKSRC);
512
513 /* load the panel info into the var struct */ 517 /* load the panel info into the var struct */
514 au1100fb_var.bits_per_pixel = fbdev->panel->bpp; 518 au1100fb_var.bits_per_pixel = fbdev->panel->bpp;
515 au1100fb_var.xres = fbdev->panel->xres; 519 au1100fb_var.xres = fbdev->panel->xres;
@@ -546,6 +550,10 @@ static int au1100fb_drv_probe(struct platform_device *dev)
546 return 0; 550 return 0;
547 551
548failed: 552failed:
553 if (fbdev->lcdclk) {
554 clk_disable_unprepare(fbdev->lcdclk);
555 clk_put(fbdev->lcdclk);
556 }
549 if (fbdev->fb_mem) { 557 if (fbdev->fb_mem) {
550 dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem, 558 dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem,
551 fbdev->fb_phys); 559 fbdev->fb_phys);
@@ -576,11 +584,15 @@ int au1100fb_drv_remove(struct platform_device *dev)
576 584
577 fb_dealloc_cmap(&fbdev->info.cmap); 585 fb_dealloc_cmap(&fbdev->info.cmap);
578 586
587 if (fbdev->lcdclk) {
588 clk_disable_unprepare(fbdev->lcdclk);
589 clk_put(fbdev->lcdclk);
590 }
591
579 return 0; 592 return 0;
580} 593}
581 594
582#ifdef CONFIG_PM 595#ifdef CONFIG_PM
583static u32 sys_clksrc;
584static struct au1100fb_regs fbregs; 596static struct au1100fb_regs fbregs;
585 597
586int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) 598int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state)
@@ -590,14 +602,11 @@ int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state)
590 if (!fbdev) 602 if (!fbdev)
591 return 0; 603 return 0;
592 604
593 /* Save the clock source state */
594 sys_clksrc = au_readl(SYS_CLKSRC);
595
596 /* Blank the LCD */ 605 /* Blank the LCD */
597 au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); 606 au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
598 607
599 /* Stop LCD clocking */ 608 if (fbdev->lcdclk)
600 au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC); 609 clk_disable(fbdev->lcdclk);
601 610
602 memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); 611 memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs));
603 612
@@ -613,8 +622,8 @@ int au1100fb_drv_resume(struct platform_device *dev)
613 622
614 memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); 623 memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs));
615 624
616 /* Restart LCD clocking */ 625 if (fbdev->lcdclk)
617 au_writel(sys_clksrc, SYS_CLKSRC); 626 clk_enable(fbdev->lcdclk);
618 627
619 /* Unblank the LCD */ 628 /* Unblank the LCD */
620 au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); 629 au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info);