summaryrefslogtreecommitdiff
path: root/arch/x86/boot/video-vga.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2009-03-19 02:54:05 +0300
committerH. Peter Anvin <hpa@linux.intel.com>2009-03-19 02:54:05 +0300
commit5f641356127712fbdce0eee120e5ce115860c17f (patch)
tree25e4fb9f3984bd2cd9621fb599e964975fad2028 /arch/x86/boot/video-vga.c
parentbe721696cac9d66566d59b205ee573ecb2f7c35b (diff)
downloadlinux-5f641356127712fbdce0eee120e5ce115860c17f.tar.xz
x86, setup: fix the setting of 480-line VGA modes
Impact: fix rarely-used feature The VGA Miscellaneous Output Register is read from address 0x3CC but written to address 0x3C2. This was missed when this code was converted from assembly to C. While we're at it, clean up the code by making the overflow bits and the math used to set the bits explicit. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/boot/video-vga.c')
-rw-r--r--arch/x86/boot/video-vga.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
index 5d4742ed4aa2..95d86ce0421c 100644
--- a/arch/x86/boot/video-vga.c
+++ b/arch/x86/boot/video-vga.c
@@ -129,41 +129,45 @@ u16 vga_crtc(void)
return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
}
-static void vga_set_480_scanlines(int end)
+static void vga_set_480_scanlines(int lines)
{
- u16 crtc;
- u8 csel;
+ u16 crtc; /* CRTC base address */
+ u8 csel; /* CRTC miscellaneous output register */
+ u8 ovfw; /* CRTC overflow register */
+ int end = lines-1;
crtc = vga_crtc();
+ ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40);
+
out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
out_idx(0x0b, crtc, 0x06); /* Vertical total */
- out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
+ out_idx(ovfw, crtc, 0x07); /* Vertical overflow */
out_idx(0xea, crtc, 0x10); /* Vertical sync start */
- out_idx(end, crtc, 0x12); /* Vertical display end */
+ out_idx(end, crtc, 0x12); /* Vertical display end */
out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
out_idx(0x04, crtc, 0x16); /* Vertical blank end */
csel = inb(0x3cc);
csel &= 0x0d;
csel |= 0xe2;
- outb(csel, 0x3cc);
+ outb(csel, 0x3c2);
}
static void vga_set_80x30(void)
{
- vga_set_480_scanlines(0xdf);
+ vga_set_480_scanlines(30*16);
}
static void vga_set_80x34(void)
{
vga_set_14font();
- vga_set_480_scanlines(0xdb);
+ vga_set_480_scanlines(34*14);
}
static void vga_set_80x60(void)
{
vga_set_8font();
- vga_set_480_scanlines(0xdf);
+ vga_set_480_scanlines(60*8);
}
static int vga_set_mode(struct mode_info *mode)