aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonino A. Daplas2005-07-29 14:03:31 -0700
committerLinus Torvalds2005-07-29 15:01:13 -0700
commit80625942094b114d85811e5ff1fbc9e06dabe0ff (patch)
tree66c6e49c4a24d7338d4510be449e4cc17dc95e29
parent655a0a7799cddf9a469916c07ac22f1106abc2be (diff)
[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.c47
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);
}
}