Skip to content

Commit 43b30be

Browse files
soci64hdeller
authored andcommitted
fbdev: s3fb: Implement powersave for S3 FB
This patch implements power saving for S3 cards by powering down the RAMDAC and stopping MCLK and DCLK while the card is supposed to be suspended. The RAMDAC is also disabled while the screen is blanked and the DCLK in stopped while in DPMS power off. The practical difference it makes is that on a machine with such a card the display will be placed in DPMS power off while standby is activated (due to stopped DCLK). Same like when using other cards with implemented power saving functionality. Without it on my setup the connected display powers up and stays that way showing VT63 while in standby. Sort of annoying as before standby it's specifically placed into DPMS off in Xorg for a while. The used functionality should exists for sure on Trio32 to Aurora64V (according to the documentation) so I think it's generally applicable. I'm using this on S3 Trio 3D and S3 Virge DX. Signed-off-by: Zsolt Kajtar <soci@c64.rulez.org> Signed-off-by: Helge Deller <deller@gmx.de>
1 parent d391bb1 commit 43b30be

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

drivers/video/fbdev/s3fb.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -988,34 +988,30 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
988988
static int s3fb_blank(int blank_mode, struct fb_info *info)
989989
{
990990
struct s3fb_info *par = info->par;
991+
u8 data;
992+
993+
data = (blank_mode == FB_BLANK_UNBLANK) ? 0x00 : 0x20;
994+
svga_wseq_mask(par->state.vgabase, 0x01, data, 0x20);
995+
svga_wseq_mask(par->state.vgabase, 0x18, data, 0x20);
991996

992997
switch (blank_mode) {
993-
case FB_BLANK_UNBLANK:
994-
fb_dbg(info, "unblank\n");
995-
svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
996-
svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
997-
break;
998-
case FB_BLANK_NORMAL:
999-
fb_dbg(info, "blank\n");
1000-
svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
1001-
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
998+
default:
999+
data = 0x00;
10021000
break;
10031001
case FB_BLANK_HSYNC_SUSPEND:
1004-
fb_dbg(info, "hsync\n");
1005-
svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06);
1006-
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
1002+
data = 0x02;
10071003
break;
10081004
case FB_BLANK_VSYNC_SUSPEND:
1009-
fb_dbg(info, "vsync\n");
1010-
svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06);
1011-
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
1005+
data = 0x04;
10121006
break;
10131007
case FB_BLANK_POWERDOWN:
1014-
fb_dbg(info, "sync down\n");
1015-
svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06);
1016-
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
1008+
data = 0x06;
10171009
break;
10181010
}
1011+
svga_wcrt_mask(par->state.vgabase, 0x56, data, 0x06);
1012+
1013+
data = (blank_mode == FB_BLANK_POWERDOWN) ? 0x01 : 0x00;
1014+
svga_wseq_mask(par->state.vgabase, 0x14, data, 0x01);
10191015

10201016
return 0;
10211017
}
@@ -1445,6 +1441,8 @@ static int __maybe_unused s3_pci_suspend(struct device *dev)
14451441
}
14461442

14471443
fb_set_suspend(info, 1);
1444+
svga_wseq_mask(par->state.vgabase, 0x18, 0x20, 0x20);
1445+
svga_wseq_mask(par->state.vgabase, 0x14, 0x03, 0x03);
14481446

14491447
mutex_unlock(&(par->open_lock));
14501448
console_unlock();
@@ -1471,6 +1469,9 @@ static int __maybe_unused s3_pci_resume(struct device *dev)
14711469
return 0;
14721470
}
14731471

1472+
vga_wseq(par->state.vgabase, 0x08, 0x06);
1473+
svga_wseq_mask(par->state.vgabase, 0x18, 0x00, 0x20);
1474+
svga_wseq_mask(par->state.vgabase, 0x14, 0x00, 0x03);
14741475
s3fb_set_par(info);
14751476
fb_set_suspend(info, 0);
14761477

0 commit comments

Comments
 (0)