aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/da8xx-fb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-11 21:21:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-11 21:21:02 -0400
commit5f76945a9c978b8b8bf8eb7fe3b17b9981240a97 (patch)
treedf61aca168df657bc71ce8b578bcb0c81b0622ee /drivers/video/da8xx-fb.c
parent940e3a8dd6683a3787faf769b3df7a06f1c2fa31 (diff)
parentcd9d6f10d07f26dd8a70e519c22b6b4f8a9e3e7a (diff)
Merge tag 'fbdev-updates-for-3.7' of git://github.com/schandinat/linux-2.6
Pull fbdev updates from Florian Tobias Schandinat: "This includes: - large updates for OMAP - basic OMAP5 DSS support for DPI and DSI outputs - large cleanups and restructuring - some update to Exynos and da8xx-fb - removal of the pnx4008 driver (arch removed) - various other small patches" Fix up some trivial conflicts (mostly just include line changes, but also some due to the renaming of the deferred work functions by Tejun). * tag 'fbdev-updates-for-3.7' of git://github.com/schandinat/linux-2.6: (193 commits) gbefb: fix compile error video: mark nuc900fb_map_video_memory as __devinit video/mx3fb: set .owner to prevent module unloading while being used video: exynos_dp: use clk_prepare_enable and clk_disable_unprepare drivers/video/exynos/exynos_mipi_dsi.c: fix error return code drivers/video/savage/savagefb_driver.c: fix error return code video: s3c-fb: use clk_prepare_enable and clk_disable_unprepare da8xx-fb: save and restore LCDC context across suspend/resume cycle da8xx-fb: add pm_runtime support video/udlfb: fix line counting in fb_write OMAPDSS: add missing include for string.h OMAPDSS: DISPC: Configure color conversion coefficients for writeback OMAPDSS: DISPC: Add manager like functions for writeback OMAPDSS: DISPC: Configure writeback FIFOs OMAPDSS: DISPC: Configure writeback specific parameters in dispc_wb_setup() OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup OMAPDSS: DISPC: Add function to set channel in for writeback OMAPDSS: DISPC: Don't set chroma resampling bit for writeback OMAPDSS: DISPC: Downscale chroma if plane is writeback OMAPDSS: DISPC: Configure input and output sizes for writeback ...
Diffstat (limited to 'drivers/video/da8xx-fb.c')
-rw-r--r--drivers/video/da8xx-fb.c283
1 files changed, 220 insertions, 63 deletions
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 113d43a16f5..80665f66ac1 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -26,7 +26,9 @@
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/uaccess.h> 28#include <linux/uaccess.h>
29#include <linux/pm_runtime.h>
29#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/wait.h>
30#include <linux/clk.h> 32#include <linux/clk.h>
31#include <linux/cpufreq.h> 33#include <linux/cpufreq.h>
32#include <linux/console.h> 34#include <linux/console.h>
@@ -48,6 +50,7 @@
48#define LCD_PL_LOAD_DONE BIT(6) 50#define LCD_PL_LOAD_DONE BIT(6)
49#define LCD_FIFO_UNDERFLOW BIT(5) 51#define LCD_FIFO_UNDERFLOW BIT(5)
50#define LCD_SYNC_LOST BIT(2) 52#define LCD_SYNC_LOST BIT(2)
53#define LCD_FRAME_DONE BIT(0)
51 54
52/* LCD DMA Control Register */ 55/* LCD DMA Control Register */
53#define LCD_DMA_BURST_SIZE(x) ((x) << 4) 56#define LCD_DMA_BURST_SIZE(x) ((x) << 4)
@@ -86,6 +89,8 @@
86#define LCD_V2_LIDD_CLK_EN BIT(1) 89#define LCD_V2_LIDD_CLK_EN BIT(1)
87#define LCD_V2_CORE_CLK_EN BIT(0) 90#define LCD_V2_CORE_CLK_EN BIT(0)
88#define LCD_V2_LPP_B10 26 91#define LCD_V2_LPP_B10 26
92#define LCD_V2_TFT_24BPP_MODE BIT(25)
93#define LCD_V2_TFT_24BPP_UNPACK BIT(26)
89 94
90/* LCD Raster Timing 2 Register */ 95/* LCD Raster Timing 2 Register */
91#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16) 96#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
@@ -135,6 +140,8 @@ static void __iomem *da8xx_fb_reg_base;
135static struct resource *lcdc_regs; 140static struct resource *lcdc_regs;
136static unsigned int lcd_revision; 141static unsigned int lcd_revision;
137static irq_handler_t lcdc_irq_handler; 142static irq_handler_t lcdc_irq_handler;
143static wait_queue_head_t frame_done_wq;
144static int frame_done_flag;
138 145
139static inline unsigned int lcdc_read(unsigned int addr) 146static inline unsigned int lcdc_read(unsigned int addr)
140{ 147{
@@ -156,7 +163,6 @@ struct da8xx_fb_par {
156 unsigned int dma_end; 163 unsigned int dma_end;
157 struct clk *lcdc_clk; 164 struct clk *lcdc_clk;
158 int irq; 165 int irq;
159 unsigned short pseudo_palette[16];
160 unsigned int palette_sz; 166 unsigned int palette_sz;
161 unsigned int pxl_clk; 167 unsigned int pxl_clk;
162 int blank; 168 int blank;
@@ -175,6 +181,7 @@ struct da8xx_fb_par {
175 unsigned int lcd_fck_rate; 181 unsigned int lcd_fck_rate;
176#endif 182#endif
177 void (*panel_power_ctrl)(int); 183 void (*panel_power_ctrl)(int);
184 u32 pseudo_palette[16];
178}; 185};
179 186
180/* Variable Screen Information */ 187/* Variable Screen Information */
@@ -288,13 +295,26 @@ static inline void lcd_enable_raster(void)
288} 295}
289 296
290/* Disable the Raster Engine of the LCD Controller */ 297/* Disable the Raster Engine of the LCD Controller */
291static inline void lcd_disable_raster(void) 298static inline void lcd_disable_raster(bool wait_for_frame_done)
292{ 299{
293 u32 reg; 300 u32 reg;
301 int ret;
294 302
295 reg = lcdc_read(LCD_RASTER_CTRL_REG); 303 reg = lcdc_read(LCD_RASTER_CTRL_REG);
296 if (reg & LCD_RASTER_ENABLE) 304 if (reg & LCD_RASTER_ENABLE)
297 lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); 305 lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
306 else
307 /* return if already disabled */
308 return;
309
310 if ((wait_for_frame_done == true) && (lcd_revision == LCD_VERSION_2)) {
311 frame_done_flag = 0;
312 ret = wait_event_interruptible_timeout(frame_done_wq,
313 frame_done_flag != 0,
314 msecs_to_jiffies(50));
315 if (ret == 0)
316 pr_err("LCD Controller timed out\n");
317 }
298} 318}
299 319
300static void lcd_blit(int load_mode, struct da8xx_fb_par *par) 320static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
@@ -321,7 +341,8 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
321 } else { 341 } else {
322 reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) | 342 reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
323 LCD_V2_END_OF_FRAME0_INT_ENA | 343 LCD_V2_END_OF_FRAME0_INT_ENA |
324 LCD_V2_END_OF_FRAME1_INT_ENA; 344 LCD_V2_END_OF_FRAME1_INT_ENA |
345 LCD_FRAME_DONE;
325 lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG); 346 lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
326 } 347 }
327 reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; 348 reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
@@ -499,6 +520,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
499{ 520{
500 u32 reg; 521 u32 reg;
501 522
523 if (bpp > 16 && lcd_revision == LCD_VERSION_1)
524 return -EINVAL;
525
502 /* Set the Panel Width */ 526 /* Set the Panel Width */
503 /* Pixels per line = (PPL + 1)*16 */ 527 /* Pixels per line = (PPL + 1)*16 */
504 if (lcd_revision == LCD_VERSION_1) { 528 if (lcd_revision == LCD_VERSION_1) {
@@ -542,14 +566,19 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
542 reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8); 566 reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
543 if (raster_order) 567 if (raster_order)
544 reg |= LCD_RASTER_ORDER; 568 reg |= LCD_RASTER_ORDER;
545 lcdc_write(reg, LCD_RASTER_CTRL_REG); 569
570 par->palette_sz = 16 * 2;
546 571
547 switch (bpp) { 572 switch (bpp) {
548 case 1: 573 case 1:
549 case 2: 574 case 2:
550 case 4: 575 case 4:
551 case 16: 576 case 16:
552 par->palette_sz = 16 * 2; 577 break;
578 case 24:
579 reg |= LCD_V2_TFT_24BPP_MODE;
580 case 32:
581 reg |= LCD_V2_TFT_24BPP_UNPACK;
553 break; 582 break;
554 583
555 case 8: 584 case 8:
@@ -560,9 +589,12 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
560 return -EINVAL; 589 return -EINVAL;
561 } 590 }
562 591
592 lcdc_write(reg, LCD_RASTER_CTRL_REG);
593
563 return 0; 594 return 0;
564} 595}
565 596
597#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
566static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, 598static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
567 unsigned blue, unsigned transp, 599 unsigned blue, unsigned transp,
568 struct fb_info *info) 600 struct fb_info *info)
@@ -578,13 +610,38 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
578 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) 610 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
579 return 1; 611 return 1;
580 612
581 if (info->var.bits_per_pixel == 4) { 613 if (info->var.bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
582 if (regno > 15) 614 return -EINVAL;
583 return 1;
584 615
585 if (info->var.grayscale) { 616 switch (info->fix.visual) {
586 pal = regno; 617 case FB_VISUAL_TRUECOLOR:
587 } else { 618 red = CNVT_TOHW(red, info->var.red.length);
619 green = CNVT_TOHW(green, info->var.green.length);
620 blue = CNVT_TOHW(blue, info->var.blue.length);
621 break;
622 case FB_VISUAL_PSEUDOCOLOR:
623 switch (info->var.bits_per_pixel) {
624 case 4:
625 if (regno > 15)
626 return -EINVAL;
627
628 if (info->var.grayscale) {
629 pal = regno;
630 } else {
631 red >>= 4;
632 green >>= 8;
633 blue >>= 12;
634
635 pal = red & 0x0f00;
636 pal |= green & 0x00f0;
637 pal |= blue & 0x000f;
638 }
639 if (regno == 0)
640 pal |= 0x2000;
641 palette[regno] = pal;
642 break;
643
644 case 8:
588 red >>= 4; 645 red >>= 4;
589 green >>= 8; 646 green >>= 8;
590 blue >>= 12; 647 blue >>= 12;
@@ -592,36 +649,36 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
592 pal = (red & 0x0f00); 649 pal = (red & 0x0f00);
593 pal |= (green & 0x00f0); 650 pal |= (green & 0x00f0);
594 pal |= (blue & 0x000f); 651 pal |= (blue & 0x000f);
595 }
596 if (regno == 0)
597 pal |= 0x2000;
598 palette[regno] = pal;
599
600 } else if (info->var.bits_per_pixel == 8) {
601 red >>= 4;
602 green >>= 8;
603 blue >>= 12;
604
605 pal = (red & 0x0f00);
606 pal |= (green & 0x00f0);
607 pal |= (blue & 0x000f);
608 652
609 if (palette[regno] != pal) { 653 if (palette[regno] != pal) {
610 update_hw = 1; 654 update_hw = 1;
611 palette[regno] = pal; 655 palette[regno] = pal;
656 }
657 break;
612 } 658 }
613 } else if ((info->var.bits_per_pixel == 16) && regno < 16) { 659 break;
614 red >>= (16 - info->var.red.length); 660 }
615 red <<= info->var.red.offset;
616 661
617 green >>= (16 - info->var.green.length); 662 /* Truecolor has hardware independent palette */
618 green <<= info->var.green.offset; 663 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
664 u32 v;
619 665
620 blue >>= (16 - info->var.blue.length); 666 if (regno > 15)
621 blue <<= info->var.blue.offset; 667 return -EINVAL;
622 668
623 par->pseudo_palette[regno] = red | green | blue; 669 v = (red << info->var.red.offset) |
670 (green << info->var.green.offset) |
671 (blue << info->var.blue.offset);
624 672
673 switch (info->var.bits_per_pixel) {
674 case 16:
675 ((u16 *) (info->pseudo_palette))[regno] = v;
676 break;
677 case 24:
678 case 32:
679 ((u32 *) (info->pseudo_palette))[regno] = v;
680 break;
681 }
625 if (palette[0] != 0x4000) { 682 if (palette[0] != 0x4000) {
626 update_hw = 1; 683 update_hw = 1;
627 palette[0] = 0x4000; 684 palette[0] = 0x4000;
@@ -634,11 +691,12 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
634 691
635 return 0; 692 return 0;
636} 693}
694#undef CNVT_TOHW
637 695
638static void lcd_reset(struct da8xx_fb_par *par) 696static void lcd_reset(struct da8xx_fb_par *par)
639{ 697{
640 /* Disable the Raster if previously Enabled */ 698 /* Disable the Raster if previously Enabled */
641 lcd_disable_raster(); 699 lcd_disable_raster(false);
642 700
643 /* DMA has to be disabled */ 701 /* DMA has to be disabled */
644 lcdc_write(0, LCD_DMA_CTRL_REG); 702 lcdc_write(0, LCD_DMA_CTRL_REG);
@@ -734,7 +792,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
734 u32 stat = lcdc_read(LCD_MASKED_STAT_REG); 792 u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
735 793
736 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { 794 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
737 lcd_disable_raster(); 795 lcd_disable_raster(false);
738 lcdc_write(stat, LCD_MASKED_STAT_REG); 796 lcdc_write(stat, LCD_MASKED_STAT_REG);
739 lcd_enable_raster(); 797 lcd_enable_raster();
740 } else if (stat & LCD_PL_LOAD_DONE) { 798 } else if (stat & LCD_PL_LOAD_DONE) {
@@ -744,7 +802,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
744 * interrupt via the following write to the status register. If 802 * interrupt via the following write to the status register. If
745 * this is done after then one gets multiple PL done interrupts. 803 * this is done after then one gets multiple PL done interrupts.
746 */ 804 */
747 lcd_disable_raster(); 805 lcd_disable_raster(false);
748 806
749 lcdc_write(stat, LCD_MASKED_STAT_REG); 807 lcdc_write(stat, LCD_MASKED_STAT_REG);
750 808
@@ -775,6 +833,14 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
775 par->vsync_flag = 1; 833 par->vsync_flag = 1;
776 wake_up_interruptible(&par->vsync_wait); 834 wake_up_interruptible(&par->vsync_wait);
777 } 835 }
836
837 /* Set only when controller is disabled and at the end of
838 * active frame
839 */
840 if (stat & BIT(0)) {
841 frame_done_flag = 1;
842 wake_up_interruptible(&frame_done_wq);
843 }
778 } 844 }
779 845
780 lcdc_write(0, LCD_END_OF_INT_IND_REG); 846 lcdc_write(0, LCD_END_OF_INT_IND_REG);
@@ -789,7 +855,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
789 u32 reg_ras; 855 u32 reg_ras;
790 856
791 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { 857 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
792 lcd_disable_raster(); 858 lcd_disable_raster(false);
793 lcdc_write(stat, LCD_STAT_REG); 859 lcdc_write(stat, LCD_STAT_REG);
794 lcd_enable_raster(); 860 lcd_enable_raster();
795 } else if (stat & LCD_PL_LOAD_DONE) { 861 } else if (stat & LCD_PL_LOAD_DONE) {
@@ -799,7 +865,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
799 * interrupt via the following write to the status register. If 865 * interrupt via the following write to the status register. If
800 * this is done after then one gets multiple PL done interrupts. 866 * this is done after then one gets multiple PL done interrupts.
801 */ 867 */
802 lcd_disable_raster(); 868 lcd_disable_raster(false);
803 869
804 lcdc_write(stat, LCD_STAT_REG); 870 lcdc_write(stat, LCD_STAT_REG);
805 871
@@ -842,6 +908,9 @@ static int fb_check_var(struct fb_var_screeninfo *var,
842{ 908{
843 int err = 0; 909 int err = 0;
844 910
911 if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
912 return -EINVAL;
913
845 switch (var->bits_per_pixel) { 914 switch (var->bits_per_pixel) {
846 case 1: 915 case 1:
847 case 8: 916 case 8:
@@ -877,6 +946,26 @@ static int fb_check_var(struct fb_var_screeninfo *var,
877 var->transp.length = 0; 946 var->transp.length = 0;
878 var->nonstd = 0; 947 var->nonstd = 0;
879 break; 948 break;
949 case 24:
950 var->red.offset = 16;
951 var->red.length = 8;
952 var->green.offset = 8;
953 var->green.length = 8;
954 var->blue.offset = 0;
955 var->blue.length = 8;
956 var->nonstd = 0;
957 break;
958 case 32:
959 var->transp.offset = 24;
960 var->transp.length = 8;
961 var->red.offset = 16;
962 var->red.length = 8;
963 var->green.offset = 8;
964 var->green.length = 8;
965 var->blue.offset = 0;
966 var->blue.length = 8;
967 var->nonstd = 0;
968 break;
880 default: 969 default:
881 err = -EINVAL; 970 err = -EINVAL;
882 } 971 }
@@ -898,9 +987,10 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
898 if (val == CPUFREQ_POSTCHANGE) { 987 if (val == CPUFREQ_POSTCHANGE) {
899 if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) { 988 if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
900 par->lcd_fck_rate = clk_get_rate(par->lcdc_clk); 989 par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
901 lcd_disable_raster(); 990 lcd_disable_raster(true);
902 lcd_calc_clk_divider(par); 991 lcd_calc_clk_divider(par);
903 lcd_enable_raster(); 992 if (par->blank == FB_BLANK_UNBLANK)
993 lcd_enable_raster();
904 } 994 }
905 } 995 }
906 996
@@ -935,7 +1025,7 @@ static int __devexit fb_remove(struct platform_device *dev)
935 if (par->panel_power_ctrl) 1025 if (par->panel_power_ctrl)
936 par->panel_power_ctrl(0); 1026 par->panel_power_ctrl(0);
937 1027
938 lcd_disable_raster(); 1028 lcd_disable_raster(true);
939 lcdc_write(0, LCD_RASTER_CTRL_REG); 1029 lcdc_write(0, LCD_RASTER_CTRL_REG);
940 1030
941 /* disable DMA */ 1031 /* disable DMA */
@@ -948,8 +1038,8 @@ static int __devexit fb_remove(struct platform_device *dev)
948 dma_free_coherent(NULL, par->vram_size, par->vram_virt, 1038 dma_free_coherent(NULL, par->vram_size, par->vram_virt,
949 par->vram_phys); 1039 par->vram_phys);
950 free_irq(par->irq, par); 1040 free_irq(par->irq, par);
951 clk_disable(par->lcdc_clk); 1041 pm_runtime_put_sync(&dev->dev);
952 clk_put(par->lcdc_clk); 1042 pm_runtime_disable(&dev->dev);
953 framebuffer_release(info); 1043 framebuffer_release(info);
954 iounmap(da8xx_fb_reg_base); 1044 iounmap(da8xx_fb_reg_base);
955 release_mem_region(lcdc_regs->start, resource_size(lcdc_regs)); 1045 release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
@@ -1051,7 +1141,7 @@ static int cfb_blank(int blank, struct fb_info *info)
1051 if (par->panel_power_ctrl) 1141 if (par->panel_power_ctrl)
1052 par->panel_power_ctrl(0); 1142 par->panel_power_ctrl(0);
1053 1143
1054 lcd_disable_raster(); 1144 lcd_disable_raster(true);
1055 break; 1145 break;
1056 default: 1146 default:
1057 ret = -EINVAL; 1147 ret = -EINVAL;
@@ -1183,9 +1273,9 @@ static int __devinit fb_probe(struct platform_device *device)
1183 ret = -ENODEV; 1273 ret = -ENODEV;
1184 goto err_ioremap; 1274 goto err_ioremap;
1185 } 1275 }
1186 ret = clk_enable(fb_clk); 1276
1187 if (ret) 1277 pm_runtime_enable(&device->dev);
1188 goto err_clk_put; 1278 pm_runtime_get_sync(&device->dev);
1189 1279
1190 /* Determine LCD IP Version */ 1280 /* Determine LCD IP Version */
1191 switch (lcdc_read(LCD_PID_REG)) { 1281 switch (lcdc_read(LCD_PID_REG)) {
@@ -1213,7 +1303,7 @@ static int __devinit fb_probe(struct platform_device *device)
1213 if (i == ARRAY_SIZE(known_lcd_panels)) { 1303 if (i == ARRAY_SIZE(known_lcd_panels)) {
1214 dev_err(&device->dev, "GLCD: No valid panel found\n"); 1304 dev_err(&device->dev, "GLCD: No valid panel found\n");
1215 ret = -ENODEV; 1305 ret = -ENODEV;
1216 goto err_clk_disable; 1306 goto err_pm_runtime_disable;
1217 } else 1307 } else
1218 dev_info(&device->dev, "GLCD: Found %s panel\n", 1308 dev_info(&device->dev, "GLCD: Found %s panel\n",
1219 fb_pdata->type); 1309 fb_pdata->type);
@@ -1225,7 +1315,7 @@ static int __devinit fb_probe(struct platform_device *device)
1225 if (!da8xx_fb_info) { 1315 if (!da8xx_fb_info) {
1226 dev_dbg(&device->dev, "Memory allocation failed for fb_info\n"); 1316 dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
1227 ret = -ENOMEM; 1317 ret = -ENOMEM;
1228 goto err_clk_disable; 1318 goto err_pm_runtime_disable;
1229 } 1319 }
1230 1320
1231 par = da8xx_fb_info->par; 1321 par = da8xx_fb_info->par;
@@ -1356,8 +1446,10 @@ static int __devinit fb_probe(struct platform_device *device)
1356 1446
1357 if (lcd_revision == LCD_VERSION_1) 1447 if (lcd_revision == LCD_VERSION_1)
1358 lcdc_irq_handler = lcdc_irq_handler_rev01; 1448 lcdc_irq_handler = lcdc_irq_handler_rev01;
1359 else 1449 else {
1450 init_waitqueue_head(&frame_done_wq);
1360 lcdc_irq_handler = lcdc_irq_handler_rev02; 1451 lcdc_irq_handler = lcdc_irq_handler_rev02;
1452 }
1361 1453
1362 ret = request_irq(par->irq, lcdc_irq_handler, 0, 1454 ret = request_irq(par->irq, lcdc_irq_handler, 0,
1363 DRIVER_NAME, par); 1455 DRIVER_NAME, par);
@@ -1385,11 +1477,9 @@ err_release_fb_mem:
1385err_release_fb: 1477err_release_fb:
1386 framebuffer_release(da8xx_fb_info); 1478 framebuffer_release(da8xx_fb_info);
1387 1479
1388err_clk_disable: 1480err_pm_runtime_disable:
1389 clk_disable(fb_clk); 1481 pm_runtime_put_sync(&device->dev);
1390 1482 pm_runtime_disable(&device->dev);
1391err_clk_put:
1392 clk_put(fb_clk);
1393 1483
1394err_ioremap: 1484err_ioremap:
1395 iounmap(da8xx_fb_reg_base); 1485 iounmap(da8xx_fb_reg_base);
@@ -1401,6 +1491,69 @@ err_request_mem:
1401} 1491}
1402 1492
1403#ifdef CONFIG_PM 1493#ifdef CONFIG_PM
1494struct lcdc_context {
1495 u32 clk_enable;
1496 u32 ctrl;
1497 u32 dma_ctrl;
1498 u32 raster_timing_0;
1499 u32 raster_timing_1;
1500 u32 raster_timing_2;
1501 u32 int_enable_set;
1502 u32 dma_frm_buf_base_addr_0;
1503 u32 dma_frm_buf_ceiling_addr_0;
1504 u32 dma_frm_buf_base_addr_1;
1505 u32 dma_frm_buf_ceiling_addr_1;
1506 u32 raster_ctrl;
1507} reg_context;
1508
1509static void lcd_context_save(void)
1510{
1511 if (lcd_revision == LCD_VERSION_2) {
1512 reg_context.clk_enable = lcdc_read(LCD_CLK_ENABLE_REG);
1513 reg_context.int_enable_set = lcdc_read(LCD_INT_ENABLE_SET_REG);
1514 }
1515
1516 reg_context.ctrl = lcdc_read(LCD_CTRL_REG);
1517 reg_context.dma_ctrl = lcdc_read(LCD_DMA_CTRL_REG);
1518 reg_context.raster_timing_0 = lcdc_read(LCD_RASTER_TIMING_0_REG);
1519 reg_context.raster_timing_1 = lcdc_read(LCD_RASTER_TIMING_1_REG);
1520 reg_context.raster_timing_2 = lcdc_read(LCD_RASTER_TIMING_2_REG);
1521 reg_context.dma_frm_buf_base_addr_0 =
1522 lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
1523 reg_context.dma_frm_buf_ceiling_addr_0 =
1524 lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
1525 reg_context.dma_frm_buf_base_addr_1 =
1526 lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
1527 reg_context.dma_frm_buf_ceiling_addr_1 =
1528 lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
1529 reg_context.raster_ctrl = lcdc_read(LCD_RASTER_CTRL_REG);
1530 return;
1531}
1532
1533static void lcd_context_restore(void)
1534{
1535 if (lcd_revision == LCD_VERSION_2) {
1536 lcdc_write(reg_context.clk_enable, LCD_CLK_ENABLE_REG);
1537 lcdc_write(reg_context.int_enable_set, LCD_INT_ENABLE_SET_REG);
1538 }
1539
1540 lcdc_write(reg_context.ctrl, LCD_CTRL_REG);
1541 lcdc_write(reg_context.dma_ctrl, LCD_DMA_CTRL_REG);
1542 lcdc_write(reg_context.raster_timing_0, LCD_RASTER_TIMING_0_REG);
1543 lcdc_write(reg_context.raster_timing_1, LCD_RASTER_TIMING_1_REG);
1544 lcdc_write(reg_context.raster_timing_2, LCD_RASTER_TIMING_2_REG);
1545 lcdc_write(reg_context.dma_frm_buf_base_addr_0,
1546 LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
1547 lcdc_write(reg_context.dma_frm_buf_ceiling_addr_0,
1548 LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
1549 lcdc_write(reg_context.dma_frm_buf_base_addr_1,
1550 LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
1551 lcdc_write(reg_context.dma_frm_buf_ceiling_addr_1,
1552 LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
1553 lcdc_write(reg_context.raster_ctrl, LCD_RASTER_CTRL_REG);
1554 return;
1555}
1556
1404static int fb_suspend(struct platform_device *dev, pm_message_t state) 1557static int fb_suspend(struct platform_device *dev, pm_message_t state)
1405{ 1558{
1406 struct fb_info *info = platform_get_drvdata(dev); 1559 struct fb_info *info = platform_get_drvdata(dev);
@@ -1411,8 +1564,9 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
1411 par->panel_power_ctrl(0); 1564 par->panel_power_ctrl(0);
1412 1565
1413 fb_set_suspend(info, 1); 1566 fb_set_suspend(info, 1);
1414 lcd_disable_raster(); 1567 lcd_disable_raster(true);
1415 clk_disable(par->lcdc_clk); 1568 lcd_context_save();
1569 pm_runtime_put_sync(&dev->dev);
1416 console_unlock(); 1570 console_unlock();
1417 1571
1418 return 0; 1572 return 0;
@@ -1423,11 +1577,14 @@ static int fb_resume(struct platform_device *dev)
1423 struct da8xx_fb_par *par = info->par; 1577 struct da8xx_fb_par *par = info->par;
1424 1578
1425 console_lock(); 1579 console_lock();
1426 clk_enable(par->lcdc_clk); 1580 pm_runtime_get_sync(&dev->dev);
1427 lcd_enable_raster(); 1581 lcd_context_restore();
1582 if (par->blank == FB_BLANK_UNBLANK) {
1583 lcd_enable_raster();
1428 1584
1429 if (par->panel_power_ctrl) 1585 if (par->panel_power_ctrl)
1430 par->panel_power_ctrl(1); 1586 par->panel_power_ctrl(1);
1587 }
1431 1588
1432 fb_set_suspend(info, 0); 1589 fb_set_suspend(info, 0);
1433 console_unlock(); 1590 console_unlock();