diff options
author | Manuel Lauss <manuel.lauss@gmail.com> | 2014-07-23 10:36:54 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-07-30 08:10:39 -0400 |
commit | 6b1889c14b4606b7a1d0e08d52664b704bbfe65f (patch) | |
tree | e10f09caee2442575a68a9a9d7d5d6921bc52945 /drivers | |
parent | 9178af9aa74edb4b161912ee1a6cbe0cc7ed7975 (diff) |
MIPS: Alchemy: au1100fb: use clk framework
Use the clock framework to en/disable the clock to the au1100
framebuffer device.
Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
Cc: Linux-MIPS <linux-mips@linux-mips.org>
Patchwork: https://patchwork.linux-mips.org/patch/7474/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/fbdev/au1100fb.c | 36 | ||||
-rw-r--r-- | drivers/video/fbdev/au1100fb.h | 1 |
2 files changed, 23 insertions, 14 deletions
diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index c163424de223..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> |
@@ -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,11 +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 = alchemy_rdsys(AU1000_SYS_CLKSRC); | ||
511 | sys_clksrc &= ~(SYS_CS_ML_MASK | SYS_CS_DL | SYS_CS_CL); | ||
512 | alchemy_wrsys((sys_clksrc | (1 << SYS_CS_ML_BIT)), AU1000_SYS_CLKSRC); | ||
513 | |||
514 | /* load the panel info into the var struct */ | 517 | /* load the panel info into the var struct */ |
515 | au1100fb_var.bits_per_pixel = fbdev->panel->bpp; | 518 | au1100fb_var.bits_per_pixel = fbdev->panel->bpp; |
516 | au1100fb_var.xres = fbdev->panel->xres; | 519 | au1100fb_var.xres = fbdev->panel->xres; |
@@ -547,6 +550,10 @@ static int au1100fb_drv_probe(struct platform_device *dev) | |||
547 | return 0; | 550 | return 0; |
548 | 551 | ||
549 | failed: | 552 | failed: |
553 | if (fbdev->lcdclk) { | ||
554 | clk_disable_unprepare(fbdev->lcdclk); | ||
555 | clk_put(fbdev->lcdclk); | ||
556 | } | ||
550 | if (fbdev->fb_mem) { | 557 | if (fbdev->fb_mem) { |
551 | dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem, | 558 | dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem, |
552 | fbdev->fb_phys); | 559 | fbdev->fb_phys); |
@@ -577,11 +584,15 @@ int au1100fb_drv_remove(struct platform_device *dev) | |||
577 | 584 | ||
578 | fb_dealloc_cmap(&fbdev->info.cmap); | 585 | fb_dealloc_cmap(&fbdev->info.cmap); |
579 | 586 | ||
587 | if (fbdev->lcdclk) { | ||
588 | clk_disable_unprepare(fbdev->lcdclk); | ||
589 | clk_put(fbdev->lcdclk); | ||
590 | } | ||
591 | |||
580 | return 0; | 592 | return 0; |
581 | } | 593 | } |
582 | 594 | ||
583 | #ifdef CONFIG_PM | 595 | #ifdef CONFIG_PM |
584 | static u32 sys_clksrc; | ||
585 | static struct au1100fb_regs fbregs; | 596 | static struct au1100fb_regs fbregs; |
586 | 597 | ||
587 | 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) |
@@ -591,14 +602,11 @@ int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) | |||
591 | if (!fbdev) | 602 | if (!fbdev) |
592 | return 0; | 603 | return 0; |
593 | 604 | ||
594 | /* Save the clock source state */ | ||
595 | sys_clksrc = alchemy_rdsys(AU1000_SYS_CLKSRC); | ||
596 | |||
597 | /* Blank the LCD */ | 605 | /* Blank the LCD */ |
598 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); | 606 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); |
599 | 607 | ||
600 | /* Stop LCD clocking */ | 608 | if (fbdev->lcdclk) |
601 | alchemy_wrsys(sys_clksrc & ~SYS_CS_ML_MASK, AU1000_SYS_CLKSRC); | 609 | clk_disable(fbdev->lcdclk); |
602 | 610 | ||
603 | memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); | 611 | memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); |
604 | 612 | ||
@@ -614,8 +622,8 @@ int au1100fb_drv_resume(struct platform_device *dev) | |||
614 | 622 | ||
615 | memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); | 623 | memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); |
616 | 624 | ||
617 | /* Restart LCD clocking */ | 625 | if (fbdev->lcdclk) |
618 | alchemy_wrsys(sys_clksrc, AU1000_SYS_CLKSRC); | 626 | clk_enable(fbdev->lcdclk); |
619 | 627 | ||
620 | /* Unblank the LCD */ | 628 | /* Unblank the LCD */ |
621 | 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 | /********************************************************************/ |