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, |