aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2013-05-13 19:58:46 -0400
committerDave Airlie <airlied@redhat.com>2013-05-30 23:37:36 -0400
commit63e28a7a5ffce59b645ca9cbcc01e1e8be56bd75 (patch)
tree9f1772e41599f71bda18c71cc78480d7576e1b73 /drivers/video
parent07ebea251d08ae851d501f7402359f053d038862 (diff)
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: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Andy Lutomirski <luto@amacapital.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/uvesafb.c70
1 files changed, 17 insertions, 53 deletions
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index e328a61b64ba..296279bc71d2 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -24,9 +24,6 @@
24#ifdef CONFIG_X86 24#ifdef CONFIG_X86
25#include <video/vga.h> 25#include <video/vga.h>
26#endif 26#endif
27#ifdef CONFIG_MTRR
28#include <asm/mtrr.h>
29#endif
30#include "edid.h" 27#include "edid.h"
31 28
32static struct cb_id uvesafb_cn_id = { 29static struct cb_id uvesafb_cn_id = {
@@ -1540,67 +1537,30 @@ static void uvesafb_init_info(struct fb_info *info, struct vbe_mode_ib *mode)
1540 1537
1541static void uvesafb_init_mtrr(struct fb_info *info) 1538static void uvesafb_init_mtrr(struct fb_info *info)
1542{ 1539{
1543#ifdef CONFIG_MTRR 1540 struct uvesafb_par *par = info->par;
1541
1544 if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) { 1542 if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
1545 int temp_size = info->fix.smem_len; 1543 int temp_size = info->fix.smem_len;
1546 unsigned int type = 0;
1547 1544
1548 switch (mtrr) { 1545 int rc;
1549 case 1:
1550 type = MTRR_TYPE_UNCACHABLE;
1551 break;
1552 case 2:
1553 type = MTRR_TYPE_WRBACK;
1554 break;
1555 case 3:
1556 type = MTRR_TYPE_WRCOMB;
1557 break;
1558 case 4:
1559 type = MTRR_TYPE_WRTHROUGH;
1560 break;
1561 default:
1562 type = 0;
1563 break;
1564 }
1565 1546
1566 if (type) { 1547 /* Find the largest power-of-two */
1567 int rc; 1548 temp_size = roundup_pow_of_two(temp_size);
1568 1549
1569 /* Find the largest power-of-two */ 1550 /* Try and find a power of two to add */
1570 temp_size = roundup_pow_of_two(temp_size); 1551 do {
1552 rc = arch_phys_wc_add(info->fix.smem_start, temp_size);
1553 temp_size >>= 1;
1554 } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
1571 1555
1572 /* Try and find a power of two to add */ 1556 if (rc >= 0)
1573 do { 1557 par->mtrr_handle = rc;
1574 rc = mtrr_add(info->fix.smem_start,
1575 temp_size, type, 1);
1576 temp_size >>= 1;
1577 } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
1578 }
1579 } 1558 }
1580#endif /* CONFIG_MTRR */
1581} 1559}
1582 1560
1583static void uvesafb_ioremap(struct fb_info *info) 1561static void uvesafb_ioremap(struct fb_info *info)
1584{ 1562{
1585#ifdef CONFIG_X86 1563 info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
1586 switch (mtrr) {
1587 case 1: /* uncachable */
1588 info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
1589 break;
1590 case 2: /* write-back */
1591 info->screen_base = ioremap_cache(info->fix.smem_start, info->fix.smem_len);
1592 break;
1593 case 3: /* write-combining */
1594 info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
1595 break;
1596 case 4: /* write-through */
1597 default:
1598 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1599 break;
1600 }
1601#else
1602 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1603#endif /* CONFIG_X86 */
1604} 1564}
1605 1565
1606static ssize_t uvesafb_show_vbe_ver(struct device *dev, 1566static ssize_t uvesafb_show_vbe_ver(struct device *dev,
@@ -1851,6 +1811,7 @@ static int uvesafb_remove(struct platform_device *dev)
1851 unregister_framebuffer(info); 1811 unregister_framebuffer(info);
1852 release_region(0x3c0, 32); 1812 release_region(0x3c0, 32);
1853 iounmap(info->screen_base); 1813 iounmap(info->screen_base);
1814 arch_phys_wc_del(par->mtrr_handle);
1854 release_mem_region(info->fix.smem_start, info->fix.smem_len); 1815 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1855 fb_destroy_modedb(info->monspecs.modedb); 1816 fb_destroy_modedb(info->monspecs.modedb);
1856 fb_dealloc_cmap(&info->cmap); 1817 fb_dealloc_cmap(&info->cmap);
@@ -1930,6 +1891,9 @@ static int uvesafb_setup(char *options)
1930 } 1891 }
1931 } 1892 }
1932 1893
1894 if (mtrr != 3 && mtrr != 1)
1895 pr_warn("uvesafb: mtrr should be set to 0 or 3; %d is unsupported", mtrr);
1896
1933 return 0; 1897 return 0;
1934} 1898}
1935#endif /* !MODULE */ 1899#endif /* !MODULE */