diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/au1100fb.c | 39 | ||||
-rw-r--r-- | drivers/video/fbdev/au1100fb.h | 1 | ||||
-rw-r--r-- | drivers/video/fbdev/au1200fb.c | 81 |
3 files changed, 63 insertions, 58 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 | ||
548 | failed: | 552 | failed: |
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 |
583 | static u32 sys_clksrc; | ||
584 | static struct au1100fb_regs fbregs; | 596 | static struct au1100fb_regs fbregs; |
585 | 597 | ||
586 | int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) | 598 | int 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); |
diff --git a/drivers/video/fbdev/au1100fb.h b/drivers/video/fbdev/au1100fb.h index 12d9642d5465..9af19939a9c6 100644 --- a/drivers/video/fbdev/au1100fb.h +++ b/drivers/video/fbdev/au1100fb.h | |||
@@ -109,6 +109,7 @@ struct au1100fb_device { | |||
109 | size_t fb_len; | 109 | size_t fb_len; |
110 | dma_addr_t fb_phys; | 110 | dma_addr_t fb_phys; |
111 | int panel_idx; | 111 | int panel_idx; |
112 | struct clk *lcdclk; | ||
112 | }; | 113 | }; |
113 | 114 | ||
114 | /********************************************************************/ | 115 | /********************************************************************/ |
diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 4cfba78a1458..40494dbdf519 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c | |||
@@ -30,6 +30,7 @@ | |||
30 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 30 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <linux/clk.h> | ||
33 | #include <linux/module.h> | 34 | #include <linux/module.h> |
34 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
35 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
@@ -330,9 +331,8 @@ struct panel_settings | |||
330 | uint32 mode_pwmhi; | 331 | uint32 mode_pwmhi; |
331 | uint32 mode_outmask; | 332 | uint32 mode_outmask; |
332 | uint32 mode_fifoctrl; | 333 | uint32 mode_fifoctrl; |
333 | uint32 mode_toyclksrc; | ||
334 | uint32 mode_backlight; | 334 | uint32 mode_backlight; |
335 | uint32 mode_auxpll; | 335 | uint32 lcdclk; |
336 | #define Xres min_xres | 336 | #define Xres min_xres |
337 | #define Yres min_yres | 337 | #define Yres min_yres |
338 | u32 min_xres; /* Minimum horizontal resolution */ | 338 | u32 min_xres; /* Minimum horizontal resolution */ |
@@ -379,9 +379,8 @@ static struct panel_settings known_lcd_panels[] = | |||
379 | .mode_pwmhi = 0x00000000, | 379 | .mode_pwmhi = 0x00000000, |
380 | .mode_outmask = 0x00FFFFFF, | 380 | .mode_outmask = 0x00FFFFFF, |
381 | .mode_fifoctrl = 0x2f2f2f2f, | 381 | .mode_fifoctrl = 0x2f2f2f2f, |
382 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
383 | .mode_backlight = 0x00000000, | 382 | .mode_backlight = 0x00000000, |
384 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 383 | .lcdclk = 96, |
385 | 320, 320, | 384 | 320, 320, |
386 | 240, 240, | 385 | 240, 240, |
387 | }, | 386 | }, |
@@ -407,9 +406,8 @@ static struct panel_settings known_lcd_panels[] = | |||
407 | .mode_pwmhi = 0x00000000, | 406 | .mode_pwmhi = 0x00000000, |
408 | .mode_outmask = 0x00FFFFFF, | 407 | .mode_outmask = 0x00FFFFFF, |
409 | .mode_fifoctrl = 0x2f2f2f2f, | 408 | .mode_fifoctrl = 0x2f2f2f2f, |
410 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
411 | .mode_backlight = 0x00000000, | 409 | .mode_backlight = 0x00000000, |
412 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 410 | .lcdclk = 96, |
413 | 640, 480, | 411 | 640, 480, |
414 | 640, 480, | 412 | 640, 480, |
415 | }, | 413 | }, |
@@ -435,9 +433,8 @@ static struct panel_settings known_lcd_panels[] = | |||
435 | .mode_pwmhi = 0x00000000, | 433 | .mode_pwmhi = 0x00000000, |
436 | .mode_outmask = 0x00FFFFFF, | 434 | .mode_outmask = 0x00FFFFFF, |
437 | .mode_fifoctrl = 0x2f2f2f2f, | 435 | .mode_fifoctrl = 0x2f2f2f2f, |
438 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
439 | .mode_backlight = 0x00000000, | 436 | .mode_backlight = 0x00000000, |
440 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 437 | .lcdclk = 96, |
441 | 800, 800, | 438 | 800, 800, |
442 | 600, 600, | 439 | 600, 600, |
443 | }, | 440 | }, |
@@ -463,9 +460,8 @@ static struct panel_settings known_lcd_panels[] = | |||
463 | .mode_pwmhi = 0x00000000, | 460 | .mode_pwmhi = 0x00000000, |
464 | .mode_outmask = 0x00FFFFFF, | 461 | .mode_outmask = 0x00FFFFFF, |
465 | .mode_fifoctrl = 0x2f2f2f2f, | 462 | .mode_fifoctrl = 0x2f2f2f2f, |
466 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
467 | .mode_backlight = 0x00000000, | 463 | .mode_backlight = 0x00000000, |
468 | .mode_auxpll = 6, /* 72MHz AUXPLL */ | 464 | .lcdclk = 72, |
469 | 1024, 1024, | 465 | 1024, 1024, |
470 | 768, 768, | 466 | 768, 768, |
471 | }, | 467 | }, |
@@ -491,9 +487,8 @@ static struct panel_settings known_lcd_panels[] = | |||
491 | .mode_pwmhi = 0x00000000, | 487 | .mode_pwmhi = 0x00000000, |
492 | .mode_outmask = 0x00FFFFFF, | 488 | .mode_outmask = 0x00FFFFFF, |
493 | .mode_fifoctrl = 0x2f2f2f2f, | 489 | .mode_fifoctrl = 0x2f2f2f2f, |
494 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
495 | .mode_backlight = 0x00000000, | 490 | .mode_backlight = 0x00000000, |
496 | .mode_auxpll = 10, /* 120MHz AUXPLL */ | 491 | .lcdclk = 120, |
497 | 1280, 1280, | 492 | 1280, 1280, |
498 | 1024, 1024, | 493 | 1024, 1024, |
499 | }, | 494 | }, |
@@ -519,9 +514,8 @@ static struct panel_settings known_lcd_panels[] = | |||
519 | .mode_pwmhi = 0x03400000, /* SCB 0x0 */ | 514 | .mode_pwmhi = 0x03400000, /* SCB 0x0 */ |
520 | .mode_outmask = 0x00FFFFFF, | 515 | .mode_outmask = 0x00FFFFFF, |
521 | .mode_fifoctrl = 0x2f2f2f2f, | 516 | .mode_fifoctrl = 0x2f2f2f2f, |
522 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
523 | .mode_backlight = 0x00000000, | 517 | .mode_backlight = 0x00000000, |
524 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 518 | .lcdclk = 96, |
525 | 1024, 1024, | 519 | 1024, 1024, |
526 | 768, 768, | 520 | 768, 768, |
527 | }, | 521 | }, |
@@ -550,9 +544,8 @@ static struct panel_settings known_lcd_panels[] = | |||
550 | .mode_pwmhi = 0x03400000, | 544 | .mode_pwmhi = 0x03400000, |
551 | .mode_outmask = 0x00fcfcfc, | 545 | .mode_outmask = 0x00fcfcfc, |
552 | .mode_fifoctrl = 0x2f2f2f2f, | 546 | .mode_fifoctrl = 0x2f2f2f2f, |
553 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
554 | .mode_backlight = 0x00000000, | 547 | .mode_backlight = 0x00000000, |
555 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 548 | .lcdclk = 96, |
556 | 640, 480, | 549 | 640, 480, |
557 | 640, 480, | 550 | 640, 480, |
558 | }, | 551 | }, |
@@ -581,9 +574,8 @@ static struct panel_settings known_lcd_panels[] = | |||
581 | .mode_pwmhi = 0x03400000, | 574 | .mode_pwmhi = 0x03400000, |
582 | .mode_outmask = 0x00fcfcfc, | 575 | .mode_outmask = 0x00fcfcfc, |
583 | .mode_fifoctrl = 0x2f2f2f2f, | 576 | .mode_fifoctrl = 0x2f2f2f2f, |
584 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
585 | .mode_backlight = 0x00000000, | 577 | .mode_backlight = 0x00000000, |
586 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 578 | .lcdclk = 96, /* 96MHz AUXPLL */ |
587 | 320, 320, | 579 | 320, 320, |
588 | 240, 240, | 580 | 240, 240, |
589 | }, | 581 | }, |
@@ -612,9 +604,8 @@ static struct panel_settings known_lcd_panels[] = | |||
612 | .mode_pwmhi = 0x03400000, | 604 | .mode_pwmhi = 0x03400000, |
613 | .mode_outmask = 0x00fcfcfc, | 605 | .mode_outmask = 0x00fcfcfc, |
614 | .mode_fifoctrl = 0x2f2f2f2f, | 606 | .mode_fifoctrl = 0x2f2f2f2f, |
615 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
616 | .mode_backlight = 0x00000000, | 607 | .mode_backlight = 0x00000000, |
617 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 608 | .lcdclk = 96, |
618 | 856, 856, | 609 | 856, 856, |
619 | 480, 480, | 610 | 480, 480, |
620 | }, | 611 | }, |
@@ -646,9 +637,8 @@ static struct panel_settings known_lcd_panels[] = | |||
646 | .mode_pwmhi = 0x00000000, | 637 | .mode_pwmhi = 0x00000000, |
647 | .mode_outmask = 0x00FFFFFF, | 638 | .mode_outmask = 0x00FFFFFF, |
648 | .mode_fifoctrl = 0x2f2f2f2f, | 639 | .mode_fifoctrl = 0x2f2f2f2f, |
649 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
650 | .mode_backlight = 0x00000000, | 640 | .mode_backlight = 0x00000000, |
651 | .mode_auxpll = (48/12) * 2, | 641 | .lcdclk = 96, |
652 | 800, 800, | 642 | 800, 800, |
653 | 480, 480, | 643 | 480, 480, |
654 | }, | 644 | }, |
@@ -764,7 +754,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, | |||
764 | 754 | ||
765 | /* Disable the window while making changes, then restore WINEN */ | 755 | /* Disable the window while making changes, then restore WINEN */ |
766 | winenable = lcd->winenable & (1 << plane); | 756 | winenable = lcd->winenable & (1 << plane); |
767 | au_sync(); | 757 | wmb(); /* drain writebuffer */ |
768 | lcd->winenable &= ~(1 << plane); | 758 | lcd->winenable &= ~(1 << plane); |
769 | lcd->window[plane].winctrl0 = winctrl0; | 759 | lcd->window[plane].winctrl0 = winctrl0; |
770 | lcd->window[plane].winctrl1 = winctrl1; | 760 | lcd->window[plane].winctrl1 = winctrl1; |
@@ -772,7 +762,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, | |||
772 | lcd->window[plane].winbuf1 = fbdev->fb_phys; | 762 | lcd->window[plane].winbuf1 = fbdev->fb_phys; |
773 | lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ | 763 | lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ |
774 | lcd->winenable |= winenable; | 764 | lcd->winenable |= winenable; |
775 | au_sync(); | 765 | wmb(); /* drain writebuffer */ |
776 | 766 | ||
777 | return 0; | 767 | return 0; |
778 | } | 768 | } |
@@ -788,22 +778,21 @@ static void au1200_setpanel(struct panel_settings *newpanel, | |||
788 | /* Make sure all windows disabled */ | 778 | /* Make sure all windows disabled */ |
789 | winenable = lcd->winenable; | 779 | winenable = lcd->winenable; |
790 | lcd->winenable = 0; | 780 | lcd->winenable = 0; |
791 | au_sync(); | 781 | wmb(); /* drain writebuffer */ |
792 | /* | 782 | /* |
793 | * Ensure everything is disabled before reconfiguring | 783 | * Ensure everything is disabled before reconfiguring |
794 | */ | 784 | */ |
795 | if (lcd->screen & LCD_SCREEN_SEN) { | 785 | if (lcd->screen & LCD_SCREEN_SEN) { |
796 | /* Wait for vertical sync period */ | 786 | /* Wait for vertical sync period */ |
797 | lcd->intstatus = LCD_INT_SS; | 787 | lcd->intstatus = LCD_INT_SS; |
798 | while ((lcd->intstatus & LCD_INT_SS) == 0) { | 788 | while ((lcd->intstatus & LCD_INT_SS) == 0) |
799 | au_sync(); | 789 | ; |
800 | } | ||
801 | 790 | ||
802 | lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ | 791 | lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ |
803 | 792 | ||
804 | do { | 793 | do { |
805 | lcd->intstatus = lcd->intstatus; /*clear interrupts*/ | 794 | lcd->intstatus = lcd->intstatus; /*clear interrupts*/ |
806 | au_sync(); | 795 | wmb(); /* drain writebuffer */ |
807 | /*wait for controller to shut down*/ | 796 | /*wait for controller to shut down*/ |
808 | } while ((lcd->intstatus & LCD_INT_SD) == 0); | 797 | } while ((lcd->intstatus & LCD_INT_SD) == 0); |
809 | 798 | ||
@@ -829,11 +818,17 @@ static void au1200_setpanel(struct panel_settings *newpanel, | |||
829 | */ | 818 | */ |
830 | if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) | 819 | if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) |
831 | { | 820 | { |
832 | uint32 sys_clksrc; | 821 | struct clk *c = clk_get(NULL, "lcd_intclk"); |
833 | au_writel(panel->mode_auxpll, SYS_AUXPLL); | 822 | long r, pc = panel->lcdclk * 1000000; |
834 | sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f; | 823 | |
835 | sys_clksrc |= panel->mode_toyclksrc; | 824 | if (!IS_ERR(c)) { |
836 | au_writel(sys_clksrc, SYS_CLKSRC); | 825 | r = clk_round_rate(c, pc); |
826 | if ((pc - r) < (pc / 10)) { /* 10% slack */ | ||
827 | clk_set_rate(c, r); | ||
828 | clk_prepare_enable(c); | ||
829 | } | ||
830 | clk_put(c); | ||
831 | } | ||
837 | } | 832 | } |
838 | 833 | ||
839 | /* | 834 | /* |
@@ -847,7 +842,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, | |||
847 | lcd->pwmhi = panel->mode_pwmhi; | 842 | lcd->pwmhi = panel->mode_pwmhi; |
848 | lcd->outmask = panel->mode_outmask; | 843 | lcd->outmask = panel->mode_outmask; |
849 | lcd->fifoctrl = panel->mode_fifoctrl; | 844 | lcd->fifoctrl = panel->mode_fifoctrl; |
850 | au_sync(); | 845 | wmb(); /* drain writebuffer */ |
851 | 846 | ||
852 | /* fixme: Check window settings to make sure still valid | 847 | /* fixme: Check window settings to make sure still valid |
853 | * for new geometry */ | 848 | * for new geometry */ |
@@ -863,7 +858,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, | |||
863 | * Re-enable screen now that it is configured | 858 | * Re-enable screen now that it is configured |
864 | */ | 859 | */ |
865 | lcd->screen |= LCD_SCREEN_SEN; | 860 | lcd->screen |= LCD_SCREEN_SEN; |
866 | au_sync(); | 861 | wmb(); /* drain writebuffer */ |
867 | 862 | ||
868 | /* Call init of panel */ | 863 | /* Call init of panel */ |
869 | if (pd->panel_init) | 864 | if (pd->panel_init) |
@@ -956,7 +951,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev) | |||
956 | | LCD_WINCTRL2_SCY_1 | 951 | | LCD_WINCTRL2_SCY_1 |
957 | ) ; | 952 | ) ; |
958 | lcd->winenable |= win->w[plane].mode_winenable; | 953 | lcd->winenable |= win->w[plane].mode_winenable; |
959 | au_sync(); | 954 | wmb(); /* drain writebuffer */ |
960 | } | 955 | } |
961 | 956 | ||
962 | 957 | ||
@@ -1270,7 +1265,7 @@ static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) | |||
1270 | 1265 | ||
1271 | if (pdata->flags & SCREEN_MASK) | 1266 | if (pdata->flags & SCREEN_MASK) |
1272 | lcd->colorkeymsk = pdata->mask; | 1267 | lcd->colorkeymsk = pdata->mask; |
1273 | au_sync(); | 1268 | wmb(); /* drain writebuffer */ |
1274 | } | 1269 | } |
1275 | 1270 | ||
1276 | static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) | 1271 | static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) |
@@ -1288,7 +1283,7 @@ static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) | |||
1288 | hi1 = (lcd->pwmhi >> 16) + 1; | 1283 | hi1 = (lcd->pwmhi >> 16) + 1; |
1289 | divider = (lcd->pwmdiv & 0x3FFFF) + 1; | 1284 | divider = (lcd->pwmdiv & 0x3FFFF) + 1; |
1290 | pdata->brightness = ((hi1 << 8) / divider) - 1; | 1285 | pdata->brightness = ((hi1 << 8) / divider) - 1; |
1291 | au_sync(); | 1286 | wmb(); /* drain writebuffer */ |
1292 | } | 1287 | } |
1293 | 1288 | ||
1294 | static void set_window(unsigned int plane, | 1289 | static void set_window(unsigned int plane, |
@@ -1387,7 +1382,7 @@ static void set_window(unsigned int plane, | |||
1387 | val |= (pdata->enable & 1) << plane; | 1382 | val |= (pdata->enable & 1) << plane; |
1388 | lcd->winenable = val; | 1383 | lcd->winenable = val; |
1389 | } | 1384 | } |
1390 | au_sync(); | 1385 | wmb(); /* drain writebuffer */ |
1391 | } | 1386 | } |
1392 | 1387 | ||
1393 | static void get_window(unsigned int plane, | 1388 | static void get_window(unsigned int plane, |
@@ -1414,7 +1409,7 @@ static void get_window(unsigned int plane, | |||
1414 | pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; | 1409 | pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; |
1415 | 1410 | ||
1416 | pdata->enable = (lcd->winenable >> plane) & 1; | 1411 | pdata->enable = (lcd->winenable >> plane) & 1; |
1417 | au_sync(); | 1412 | wmb(); /* drain writebuffer */ |
1418 | } | 1413 | } |
1419 | 1414 | ||
1420 | static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, | 1415 | static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, |
@@ -1511,7 +1506,7 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id) | |||
1511 | { | 1506 | { |
1512 | /* Nothing to do for now, just clear any pending interrupt */ | 1507 | /* Nothing to do for now, just clear any pending interrupt */ |
1513 | lcd->intstatus = lcd->intstatus; | 1508 | lcd->intstatus = lcd->intstatus; |
1514 | au_sync(); | 1509 | wmb(); /* drain writebuffer */ |
1515 | 1510 | ||
1516 | return IRQ_HANDLED; | 1511 | return IRQ_HANDLED; |
1517 | } | 1512 | } |
@@ -1809,7 +1804,7 @@ static int au1200fb_drv_suspend(struct device *dev) | |||
1809 | au1200_setpanel(NULL, pd); | 1804 | au1200_setpanel(NULL, pd); |
1810 | 1805 | ||
1811 | lcd->outmask = 0; | 1806 | lcd->outmask = 0; |
1812 | au_sync(); | 1807 | wmb(); /* drain writebuffer */ |
1813 | 1808 | ||
1814 | return 0; | 1809 | return 0; |
1815 | } | 1810 | } |