Commit ebf4fd17 authored by Antonino Daplas's avatar Antonino Daplas Committed by Linus Torvalds

[PATCH] fbdev: use 8-bit DAC for capable hardware

The patch adds the ability for vesafb to switch the DAC from 6-bit to 8-bit
at kernel boot.  Besides fixing the failure to draw the 224-color logo, an
8-bit DAC will also provide a wider color range for user applications.
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 216f473e
......@@ -232,6 +232,41 @@ mopar_gr:
xorl %eax, %eax
movw 18(%di), %ax
movl %eax, %fs:(PARAM_LFB_SIZE)
# switching the DAC to 8-bit is for <= 8 bpp only
movw %fs:(PARAM_LFB_DEPTH), %ax
cmpw $8, %ax
jg dac_done
# get DAC switching capability
xorl %eax, %eax
movb 10(%di), %al
testb $1, %al
jz dac_set
# attempt to switch DAC to 8-bit
movw $0x4f08, %ax
movw $0x0800, %bx
int $0x10
cmpw $0x004f, %ax
jne dac_set
movb %bh, dac_size # store actual DAC size
dac_set:
# set color size to DAC size
movb dac_size, %al
movb %al, %fs:(PARAM_LFB_COLORS+0)
movb %al, %fs:(PARAM_LFB_COLORS+2)
movb %al, %fs:(PARAM_LFB_COLORS+4)
movb %al, %fs:(PARAM_LFB_COLORS+6)
# set color offsets to 0
movb $0, %fs:(PARAM_LFB_COLORS+1)
movb $0, %fs:(PARAM_LFB_COLORS+3)
movb $0, %fs:(PARAM_LFB_COLORS+5)
movb $0, %fs:(PARAM_LFB_COLORS+7)
dac_done:
# get protected mode interface informations
movw $0x4f0a, %ax
xorw %bx, %bx
......@@ -1929,6 +1964,7 @@ scanning: .byte 0 # Performing mode scan
do_restore: .byte 0 # Screen contents altered during mode change
svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes
graphic_mode: .byte 0 # Graphic mode with a linear frame buffer
dac_size: .byte 6 # DAC bit depth
# Status messages
keymsg: .ascii "Press <RETURN> to see video modes available, "
......
......@@ -87,15 +87,17 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var,
return 0;
}
static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
static void vesa_setpalette(int regno, unsigned red, unsigned green,
unsigned blue, struct fb_var_screeninfo *var)
{
#ifdef __i386__
struct { u_char blue, green, red, pad; } entry;
int shift = 16 - var->green.length;
if (pmi_setpal) {
entry.red = red >> 10;
entry.green = green >> 10;
entry.blue = blue >> 10;
entry.red = red >> shift;
entry.green = green >> shift;
entry.blue = blue >> shift;
entry.pad = 0;
__asm__ __volatile__(
"call *(%%esi)"
......@@ -109,9 +111,9 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned bl
} else {
/* without protected mode interface, try VGA registers... */
outb_p(regno, dac_reg);
outb_p(red >> 10, dac_val);
outb_p(green >> 10, dac_val);
outb_p(blue >> 10, dac_val);
outb_p(red >> shift, dac_val);
outb_p(green >> shift, dac_val);
outb_p(blue >> shift, dac_val);
}
#endif
}
......@@ -132,7 +134,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
switch (info->var.bits_per_pixel) {
case 8:
vesa_setpalette(regno,red,green,blue);
vesa_setpalette(regno,red,green,blue, &info->var);
break;
case 16:
if (info->var.red.offset == 10) {
......@@ -331,7 +333,6 @@ static int __init vesafb_probe(struct device *device)
vesafb_defined.left_margin = (vesafb_defined.xres / 8) & 0xf8;
vesafb_defined.hsync_len = (vesafb_defined.xres / 8) & 0xf8;
if (vesafb_defined.bits_per_pixel > 8) {
vesafb_defined.red.offset = screen_info.red_pos;
vesafb_defined.red.length = screen_info.red_size;
vesafb_defined.green.offset = screen_info.green_pos;
......@@ -340,8 +341,10 @@ static int __init vesafb_probe(struct device *device)
vesafb_defined.blue.length = screen_info.blue_size;
vesafb_defined.transp.offset = screen_info.rsvd_pos;
vesafb_defined.transp.length = screen_info.rsvd_size;
printk(KERN_INFO "vesafb: directcolor: "
printk(KERN_INFO "vesafb: %s: "
"size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
(vesafb_defined.bits_per_pixel > 8) ?
"Truecolor" : "Pseudocolor",
screen_info.rsvd_size,
screen_info.red_size,
screen_info.green_size,
......@@ -350,11 +353,6 @@ static int __init vesafb_probe(struct device *device)
screen_info.red_pos,
screen_info.green_pos,
screen_info.blue_pos);
} else {
vesafb_defined.red.length = 6;
vesafb_defined.green.length = 6;
vesafb_defined.blue.length = 6;
}
vesafb_fix.ypanstep = ypan ? 1 : 0;
vesafb_fix.ywrapstep = (ypan>1) ? 1 : 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment