Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63e28a7a authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Dave Airlie
Browse files

uvesafb: Clean up MTRR code



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: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarAndy Lutomirski <luto@amacapital.net>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 07ebea25
Loading
Loading
Loading
Loading
+5 −11
Original line number Original line Diff line number Diff line
@@ -81,17 +81,11 @@ pmipal Use the protected mode interface for palette changes.


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

              3 - write-combining
	Values other than 0 and 3 will result in a warning and will be
              4 - write-through
	treated just like 3.

        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
...


nomtrr  Do not use memory type range registers.
nomtrr  Do not use memory type range registers.


+17 −53
Original line number Original line Diff line number Diff line
@@ -24,9 +24,6 @@
#ifdef CONFIG_X86
#ifdef CONFIG_X86
#include <video/vga.h>
#include <video/vga.h>
#endif
#endif
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include "edid.h"
#include "edid.h"


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


static void uvesafb_init_mtrr(struct fb_info *info)
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))) {
	if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
		int temp_size = info->fix.smem_len;
		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;
		}


		if (type) {
		int rc;
		int rc;


		/* Find the largest power-of-two */
		/* Find the largest power-of-two */
@@ -1571,36 +1549,18 @@ static void uvesafb_init_mtrr(struct fb_info *info)


		/* Try and find a power of two to add */
		/* Try and find a power of two to add */
		do {
		do {
				rc = mtrr_add(info->fix.smem_start,
			rc = arch_phys_wc_add(info->fix.smem_start, temp_size);
					      temp_size, type, 1);
			temp_size >>= 1;
			temp_size >>= 1;
		} while (temp_size >= PAGE_SIZE && rc == -EINVAL);
		} 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)
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);
	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 */
}
}


static ssize_t uvesafb_show_vbe_ver(struct device *dev,
static ssize_t uvesafb_show_vbe_ver(struct device *dev,
@@ -1851,6 +1811,7 @@ static int uvesafb_remove(struct platform_device *dev)
		unregister_framebuffer(info);
		unregister_framebuffer(info);
		release_region(0x3c0, 32);
		release_region(0x3c0, 32);
		iounmap(info->screen_base);
		iounmap(info->screen_base);
		arch_phys_wc_del(par->mtrr_handle);
		release_mem_region(info->fix.smem_start, info->fix.smem_len);
		release_mem_region(info->fix.smem_start, info->fix.smem_len);
		fb_destroy_modedb(info->monspecs.modedb);
		fb_destroy_modedb(info->monspecs.modedb);
		fb_dealloc_cmap(&info->cmap);
		fb_dealloc_cmap(&info->cmap);
@@ -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;
	return 0;
}
}
#endif /* !MODULE */
#endif /* !MODULE */
+1 −0
Original line number Original line Diff line number Diff line
@@ -134,6 +134,7 @@ struct uvesafb_par {


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


#endif /* _UVESAFB_H */
#endif /* _UVESAFB_H */