diff options
Diffstat (limited to 'drivers/video/sm501fb.c')
-rw-r--r-- | drivers/video/sm501fb.c | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 58f200c69be3..e83dfba7e636 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -641,6 +641,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to) | |||
641 | { | 641 | { |
642 | unsigned long control; | 642 | unsigned long control; |
643 | void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL; | 643 | void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL; |
644 | struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl; | ||
644 | 645 | ||
645 | control = readl(ctrl_reg); | 646 | control = readl(ctrl_reg); |
646 | 647 | ||
@@ -657,26 +658,34 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to) | |||
657 | sm501fb_sync_regs(fbi); | 658 | sm501fb_sync_regs(fbi); |
658 | mdelay(10); | 659 | mdelay(10); |
659 | 660 | ||
660 | control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ | 661 | if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) { |
661 | writel(control, ctrl_reg); | 662 | control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ |
662 | sm501fb_sync_regs(fbi); | 663 | writel(control, ctrl_reg); |
663 | mdelay(10); | 664 | sm501fb_sync_regs(fbi); |
664 | 665 | mdelay(10); | |
665 | control |= SM501_DC_PANEL_CONTROL_FPEN; | 666 | } |
666 | writel(control, ctrl_reg); | ||
667 | 667 | ||
668 | if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) { | ||
669 | control |= SM501_DC_PANEL_CONTROL_FPEN; | ||
670 | writel(control, ctrl_reg); | ||
671 | sm501fb_sync_regs(fbi); | ||
672 | mdelay(10); | ||
673 | } | ||
668 | } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { | 674 | } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { |
669 | /* disable panel power */ | 675 | /* disable panel power */ |
676 | if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) { | ||
677 | control &= ~SM501_DC_PANEL_CONTROL_FPEN; | ||
678 | writel(control, ctrl_reg); | ||
679 | sm501fb_sync_regs(fbi); | ||
680 | mdelay(10); | ||
681 | } | ||
670 | 682 | ||
671 | control &= ~SM501_DC_PANEL_CONTROL_FPEN; | 683 | if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) { |
672 | writel(control, ctrl_reg); | 684 | control &= ~SM501_DC_PANEL_CONTROL_BIAS; |
673 | sm501fb_sync_regs(fbi); | 685 | writel(control, ctrl_reg); |
674 | mdelay(10); | 686 | sm501fb_sync_regs(fbi); |
675 | 687 | mdelay(10); | |
676 | control &= ~SM501_DC_PANEL_CONTROL_BIAS; | 688 | } |
677 | writel(control, ctrl_reg); | ||
678 | sm501fb_sync_regs(fbi); | ||
679 | mdelay(10); | ||
680 | 689 | ||
681 | control &= ~SM501_DC_PANEL_CONTROL_DATA; | 690 | control &= ~SM501_DC_PANEL_CONTROL_DATA; |
682 | writel(control, ctrl_reg); | 691 | writel(control, ctrl_reg); |
@@ -1267,6 +1276,7 @@ static int sm501fb_start(struct sm501fb_info *info, | |||
1267 | { | 1276 | { |
1268 | struct resource *res; | 1277 | struct resource *res; |
1269 | struct device *dev; | 1278 | struct device *dev; |
1279 | int k; | ||
1270 | int ret; | 1280 | int ret; |
1271 | 1281 | ||
1272 | info->dev = dev = &pdev->dev; | 1282 | info->dev = dev = &pdev->dev; |
@@ -1328,6 +1338,13 @@ static int sm501fb_start(struct sm501fb_info *info, | |||
1328 | 1338 | ||
1329 | info->fbmem_len = (res->end - res->start)+1; | 1339 | info->fbmem_len = (res->end - res->start)+1; |
1330 | 1340 | ||
1341 | /* clear framebuffer memory - avoids garbage data on unused fb */ | ||
1342 | memset(info->fbmem, 0, info->fbmem_len); | ||
1343 | |||
1344 | /* clear palette ram - undefined at power on */ | ||
1345 | for (k = 0; k < (256 * 3); k++) | ||
1346 | writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4)); | ||
1347 | |||
1331 | /* enable display controller */ | 1348 | /* enable display controller */ |
1332 | sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); | 1349 | sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); |
1333 | 1350 | ||
@@ -1681,6 +1698,15 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info, | |||
1681 | if (par->screen.size == 0) | 1698 | if (par->screen.size == 0) |
1682 | return 0; | 1699 | return 0; |
1683 | 1700 | ||
1701 | /* blank the relevant interface to ensure unit power minimised */ | ||
1702 | (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi); | ||
1703 | |||
1704 | /* tell console/fb driver we are suspending */ | ||
1705 | |||
1706 | acquire_console_sem(); | ||
1707 | fb_set_suspend(fbi, 1); | ||
1708 | release_console_sem(); | ||
1709 | |||
1684 | /* backup copies in case chip is powered down over suspend */ | 1710 | /* backup copies in case chip is powered down over suspend */ |
1685 | 1711 | ||
1686 | par->store_fb = vmalloc(par->screen.size); | 1712 | par->store_fb = vmalloc(par->screen.size); |
@@ -1700,12 +1726,6 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info, | |||
1700 | 1726 | ||
1701 | memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size); | 1727 | memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size); |
1702 | memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size); | 1728 | memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size); |
1703 | /* blank the relevant interface to ensure unit power minimised */ | ||
1704 | (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi); | ||
1705 | |||
1706 | acquire_console_sem(); | ||
1707 | fb_set_suspend(fbi, 1); | ||
1708 | release_console_sem(); | ||
1709 | 1729 | ||
1710 | return 0; | 1730 | return 0; |
1711 | 1731 | ||