aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/vesafb.c
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2006-04-11 01:55:48 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-11 09:18:54 -0400
commit89ec4c238e7a3d7e660291f3f1a8181381baad77 (patch)
tree8ba2ab49cea71cfff21ee7a56717f83746cb8d0c /drivers/video/vesafb.c
parentac50ab3e45436900b5d73edd0c6b0744af560535 (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/vesafb.c')
-rw-r--r--drivers/video/vesafb.c27
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;
57static void (*pmi_start)(void); 57static void (*pmi_start)(void);
58static void (*pmi_pal)(void); 58static void (*pmi_pal)(void);
59static int depth; 59static int depth;
60 60static int vga_compat;
61/* --------------------------------------------------------------------- */ 61/* --------------------------------------------------------------------- */
62 62
63static int vesafb_pan_display(struct fb_var_screeninfo *var, 63static int vesafb_pan_display(struct fb_var_screeninfo *var,
@@ -83,9 +83,10 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var,
83static void vesa_setpalette(int regno, unsigned red, unsigned green, 83static 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
114static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, 121static 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,