[PATCH] vesafb: Fix mtrr bugs

>> vesafb: mode is 800x600x16, linelength=1600, pages=16
>> vesafb: scrolling: redraw
>> vesafb: Truecolor: size=0:5:6:5, shift=0:11:5:0
>> mtrr: type mismatch for fc000000,1000000 old: write-back new: write-
>> combining

Range is already set to write-back, vesafb attempts to add a write-combining
mtrr (default for vesafb).

>> mtrr: size and base must be multiples of 4 kiB

This is a bug, vesafb attempts to add a size < PAGE_SIZE triggering
the messages below.

To eliminate the warning messages, you can add the option mtrr:2 to add a
write-back mtrr for vesafb.  Or just use nomtrr option.

1. Fix algorithm for finding the best power of 2 size with mtrr_add().

2. Add option to choose the mtrr type by extending the mtrr boot option:

   mtrr:n where n

        0 = no mtrr (equivalent to using the nomtrr option)
        1 = uncachable
        2 = write back
        3 = write combining (default)
        4 = write through

Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Antonino A. Daplas 2005-07-29 14:03:31 -07:00 committed by Linus Torvalds
parent 655a0a7799
commit 8062594209

View file

@ -45,7 +45,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
};
static int inverse = 0;
static int mtrr = 1;
static int mtrr = 3; /* default to write-combining */
static int vram_remap __initdata = 0; /* Set amount of memory to be used */
static int vram_total __initdata = 0; /* Set total amount of memory */
static int pmi_setpal = 0; /* pmi for palette changes ??? */
@ -204,8 +204,8 @@ static int __init vesafb_setup(char *options)
pmi_setpal=0;
else if (! strcmp(this_opt, "pmipal"))
pmi_setpal=1;
else if (! strcmp(this_opt, "mtrr"))
mtrr=1;
else if (! strncmp(this_opt, "mtrr:", 5))
mtrr = simple_strtoul(this_opt+5, NULL, 0);
else if (! strcmp(this_opt, "nomtrr"))
mtrr=0;
else if (! strncmp(this_opt, "vtotal:", 7))
@ -387,14 +387,39 @@ static int __init vesafb_probe(struct device *device)
if (mtrr) {
unsigned int temp_size = size_total;
/* Find the largest power-of-two */
while (temp_size & (temp_size - 1))
temp_size &= (temp_size - 1);
unsigned int type = 0;
/* Try and find a power of two to add */
while (temp_size > PAGE_SIZE &&
mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) {
temp_size >>= 1;
switch (mtrr) {
case 1:
type = MTRR_TYPE_UNCACHABLE;
break;
case 2:
type = MTRR_TYPE_WRBACK;
break;
case 3:
type = MTRR_TYPE_WRCOMB;
break;
case 4:
type = MTRR_TYPE_WRTHROUGH;
break;
default:
type = 0;
break;
}
if (type) {
int rc;
/* Find the largest power-of-two */
while (temp_size & (temp_size - 1))
temp_size &= (temp_size - 1);
/* Try and find a power of two to add */
do {
rc = mtrr_add(vesafb_fix.smem_start, temp_size,
type, 1);
temp_size >>= 1;
} while (temp_size >= PAGE_SIZE && rc == -EINVAL);
}
}