diff options
author | Antonino A. Daplas <adaplas@gmail.com> | 2005-07-29 14:03:31 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-29 15:01:13 -0700 |
commit | 80625942094b114d85811e5ff1fbc9e06dabe0ff (patch) | |
tree | 66c6e49c4a24d7338d4510be449e4cc17dc95e29 | |
parent | 655a0a7799cddf9a469916c07ac22f1106abc2be (diff) | |
download | linux-80625942094b114d85811e5ff1fbc9e06dabe0ff.tar.gz linux-80625942094b114d85811e5ff1fbc9e06dabe0ff.tar.bz2 linux-80625942094b114d85811e5ff1fbc9e06dabe0ff.zip |
[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>
-rw-r--r-- | drivers/video/vesafb.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 9ed1a931dd31..a272592b0373 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -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); - - /* 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; + unsigned int type = 0; + + 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); } } |