Skip to content

Commit

Permalink
uvesafb: Clean up MTRR code
Browse files Browse the repository at this point in the history
The old code allowed very strange memory types.  Now it works like
all the other video drivers: ioremap_wc is used unconditionally,
and MTRRs are set if PAT is unavailable (unless MTRR is disabled
by a module parameter).

UC, WB, and WT support is gone.  If there are MTRR conflicts that prevent
addition of a WC MTRR, adding a non-conflicting MTRR is pointless; it's
better to just turn off MTRR support entirely.

As an added bonus, any MTRR added is freed on unload.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Andy Lutomirski authored and Dave Airlie committed May 31, 2013
1 parent 07ebea2 commit 63e28a7
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 64 deletions.
16 changes: 5 additions & 11 deletions Documentation/fb/uvesafb.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,11 @@ pmipal Use the protected mode interface for palette changes.

mtrr:n Setup memory type range registers for the framebuffer
where n:
0 - disabled (equivalent to nomtrr) (default)
1 - uncachable
2 - write-back
3 - write-combining
4 - write-through

If you see the following in dmesg, choose the type that matches
the old one. In this example, use "mtrr:2".
...
mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
...
0 - disabled (equivalent to nomtrr)
3 - write-combining (default)

Values other than 0 and 3 will result in a warning and will be
treated just like 3.

nomtrr Do not use memory type range registers.

Expand Down
70 changes: 17 additions & 53 deletions drivers/video/uvesafb.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
#ifdef CONFIG_X86
#include <video/vga.h>
#endif
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include "edid.h"

static struct cb_id uvesafb_cn_id = {
Expand Down Expand Up @@ -1540,67 +1537,30 @@ static void uvesafb_init_info(struct fb_info *info, struct vbe_mode_ib *mode)

static void uvesafb_init_mtrr(struct fb_info *info)
{
#ifdef CONFIG_MTRR
struct uvesafb_par *par = info->par;

if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
int temp_size = info->fix.smem_len;
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;
}
int rc;

if (type) {
int rc;
/* Find the largest power-of-two */
temp_size = roundup_pow_of_two(temp_size);

/* Find the largest power-of-two */
temp_size = roundup_pow_of_two(temp_size);
/* Try and find a power of two to add */
do {
rc = arch_phys_wc_add(info->fix.smem_start, temp_size);
temp_size >>= 1;
} while (temp_size >= PAGE_SIZE && rc == -EINVAL);

/* Try and find a power of two to add */
do {
rc = mtrr_add(info->fix.smem_start,
temp_size, type, 1);
temp_size >>= 1;
} while (temp_size >= PAGE_SIZE && rc == -EINVAL);
}
if (rc >= 0)
par->mtrr_handle = rc;
}
#endif /* CONFIG_MTRR */
}

static void uvesafb_ioremap(struct fb_info *info)
{
#ifdef CONFIG_X86
switch (mtrr) {
case 1: /* uncachable */
info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
break;
case 2: /* write-back */
info->screen_base = ioremap_cache(info->fix.smem_start, info->fix.smem_len);
break;
case 3: /* write-combining */
info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
break;
case 4: /* write-through */
default:
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
break;
}
#else
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
#endif /* CONFIG_X86 */
info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
}

static ssize_t uvesafb_show_vbe_ver(struct device *dev,
Expand Down Expand Up @@ -1851,6 +1811,7 @@ static int uvesafb_remove(struct platform_device *dev)
unregister_framebuffer(info);
release_region(0x3c0, 32);
iounmap(info->screen_base);
arch_phys_wc_del(par->mtrr_handle);
release_mem_region(info->fix.smem_start, info->fix.smem_len);
fb_destroy_modedb(info->monspecs.modedb);
fb_dealloc_cmap(&info->cmap);
Expand Down Expand Up @@ -1930,6 +1891,9 @@ static int uvesafb_setup(char *options)
}
}

if (mtrr != 3 && mtrr != 1)
pr_warn("uvesafb: mtrr should be set to 0 or 3; %d is unsupported", mtrr);

return 0;
}
#endif /* !MODULE */
Expand Down
1 change: 1 addition & 0 deletions include/video/uvesafb.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct uvesafb_par {

int mode_idx;
struct vbe_crtc_ib crtc;
int mtrr_handle;
};

#endif /* _UVESAFB_H */

0 comments on commit 63e28a7

Please sign in to comment.