diff options
| author | Antonino A. Daplas <adaplas@gmail.com> | 2006-04-11 01:55:48 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-11 09:18:54 -0400 |
| commit | 89ec4c238e7a3d7e660291f3f1a8181381baad77 (patch) | |
| tree | 8ba2ab49cea71cfff21ee7a56717f83746cb8d0c /drivers/video | |
| parent | ac50ab3e45436900b5d73edd0c6b0744af560535 (diff) | |
[PATCH] vesafb: Fix incorrect logo colors in x86_64
Bugzilla Bug 6299:
A pixel size of 8 bits produces wrong logo colors in x86_64.
The driver has 2 methods for setting the color map, using the protected
mode interface provided by the video BIOS and directly writing to the VGA
registers. The former is not supported in x86_64 and the latter is enabled
only in i386.
Fix by enabling the latter method in x86_64 only if supported by the BIOS.
If both methods are unsupported, change the visual of vesafb to
STATIC_PSEUDOCOLOR.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video')
| -rw-r--r-- | drivers/video/vesafb.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 8982e540214c..b0b9acfdd430 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
| @@ -57,7 +57,7 @@ static unsigned short *pmi_base = NULL; | |||
| 57 | static void (*pmi_start)(void); | 57 | static void (*pmi_start)(void); |
| 58 | static void (*pmi_pal)(void); | 58 | static void (*pmi_pal)(void); |
| 59 | static int depth; | 59 | static int depth; |
| 60 | 60 | static int vga_compat; | |
| 61 | /* --------------------------------------------------------------------- */ | 61 | /* --------------------------------------------------------------------- */ |
| 62 | 62 | ||
| 63 | static int vesafb_pan_display(struct fb_var_screeninfo *var, | 63 | static int vesafb_pan_display(struct fb_var_screeninfo *var, |
| @@ -83,9 +83,10 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, | |||
| 83 | static void vesa_setpalette(int regno, unsigned red, unsigned green, | 83 | static void vesa_setpalette(int regno, unsigned red, unsigned green, |
| 84 | unsigned blue) | 84 | unsigned blue) |
| 85 | { | 85 | { |
| 86 | int shift = 16 - depth; | ||
| 87 | |||
| 86 | #ifdef __i386__ | 88 | #ifdef __i386__ |
| 87 | struct { u_char blue, green, red, pad; } entry; | 89 | struct { u_char blue, green, red, pad; } entry; |
| 88 | int shift = 16 - depth; | ||
| 89 | 90 | ||
| 90 | if (pmi_setpal) { | 91 | if (pmi_setpal) { |
| 91 | entry.red = red >> shift; | 92 | entry.red = red >> shift; |
| @@ -101,14 +102,20 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green, | |||
| 101 | "d" (regno), /* EDX */ | 102 | "d" (regno), /* EDX */ |
| 102 | "D" (&entry), /* EDI */ | 103 | "D" (&entry), /* EDI */ |
| 103 | "S" (&pmi_pal)); /* ESI */ | 104 | "S" (&pmi_pal)); /* ESI */ |
| 104 | } else { | 105 | return; |
| 105 | /* without protected mode interface, try VGA registers... */ | 106 | } |
| 107 | #endif | ||
| 108 | |||
| 109 | /* | ||
| 110 | * without protected mode interface and if VGA compatible, | ||
| 111 | * try VGA registers... | ||
| 112 | */ | ||
| 113 | if (vga_compat) { | ||
| 106 | outb_p(regno, dac_reg); | 114 | outb_p(regno, dac_reg); |
| 107 | outb_p(red >> shift, dac_val); | 115 | outb_p(red >> shift, dac_val); |
| 108 | outb_p(green >> shift, dac_val); | 116 | outb_p(green >> shift, dac_val); |
| 109 | outb_p(blue >> shift, dac_val); | 117 | outb_p(blue >> shift, dac_val); |
| 110 | } | 118 | } |
| 111 | #endif | ||
| 112 | } | 119 | } |
| 113 | 120 | ||
| 114 | static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, | 121 | static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, |
| @@ -214,6 +221,7 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
| 214 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) | 221 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) |
| 215 | return -ENODEV; | 222 | return -ENODEV; |
| 216 | 223 | ||
| 224 | vga_compat = (screen_info.capabilities & 2) ? 0 : 1; | ||
| 217 | vesafb_fix.smem_start = screen_info.lfb_base; | 225 | vesafb_fix.smem_start = screen_info.lfb_base; |
| 218 | vesafb_defined.bits_per_pixel = screen_info.lfb_depth; | 226 | vesafb_defined.bits_per_pixel = screen_info.lfb_depth; |
| 219 | if (15 == vesafb_defined.bits_per_pixel) | 227 | if (15 == vesafb_defined.bits_per_pixel) |
| @@ -318,6 +326,12 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
| 318 | } | 326 | } |
| 319 | } | 327 | } |
| 320 | 328 | ||
| 329 | if (vesafb_defined.bits_per_pixel == 8 && !pmi_setpal && !vga_compat) { | ||
| 330 | printk(KERN_WARNING "vesafb: hardware palette is unchangeable,\n" | ||
| 331 | " colors may be incorrect\n"); | ||
| 332 | vesafb_fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; | ||
| 333 | } | ||
| 334 | |||
| 321 | vesafb_defined.xres_virtual = vesafb_defined.xres; | 335 | vesafb_defined.xres_virtual = vesafb_defined.xres; |
| 322 | vesafb_defined.yres_virtual = vesafb_fix.smem_len / vesafb_fix.line_length; | 336 | vesafb_defined.yres_virtual = vesafb_fix.smem_len / vesafb_fix.line_length; |
| 323 | if (ypan && vesafb_defined.yres_virtual > vesafb_defined.yres) { | 337 | if (ypan && vesafb_defined.yres_virtual > vesafb_defined.yres) { |
| @@ -354,7 +368,8 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
| 354 | printk(KERN_INFO "vesafb: %s: " | 368 | printk(KERN_INFO "vesafb: %s: " |
| 355 | "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", | 369 | "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", |
| 356 | (vesafb_defined.bits_per_pixel > 8) ? | 370 | (vesafb_defined.bits_per_pixel > 8) ? |
| 357 | "Truecolor" : "Pseudocolor", | 371 | "Truecolor" : (vga_compat || pmi_setpal) ? |
| 372 | "Pseudocolor" : "Static Pseudocolor", | ||
| 358 | screen_info.rsvd_size, | 373 | screen_info.rsvd_size, |
| 359 | screen_info.red_size, | 374 | screen_info.red_size, |
| 360 | screen_info.green_size, | 375 | screen_info.green_size, |
