aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/fb/uvesafb.txt16
-rw-r--r--drivers/video/uvesafb.c70
-rw-r--r--include/video/uvesafb.h1
3 files changed, 23 insertions, 64 deletions
diff --git a/Documentation/fb/uvesafb.txt b/Documentation/fb/uvesafb.txt
index eefdd91d298a..f6362d88763b 100644
--- a/Documentation/fb/uvesafb.txt
+++ b/Documentation/fb/uvesafb.txt
@@ -81,17 +81,11 @@ pmipal Use the protected mode interface for palette changes.
81 81
82mtrr:n Setup memory type range registers for the framebuffer 82mtrr:n Setup memory type range registers for the framebuffer
83 where n: 83 where n:
84 0 - disabled (equivalent to nomtrr) (default) 84 0 - disabled (equivalent to nomtrr)
85 1 - uncachable 85 3 - write-combining (default)
86 2 - write-back 86
87 3 - write-combining 87 Values other than 0 and 3 will result in a warning and will be
88 4 - write-through 88 treated just like 3.
89
90 If you see the following in dmesg, choose the type that matches
91 the old one. In this example, use "mtrr:2".
92...
93mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
94...
95 89
96nomtrr Do not use memory type range registers. 90nomtrr Do not use memory type range registers.
97 91
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 */
diff --git a/include/video/uvesafb.h b/include/video/uvesafb.h
index 1a91850cb961..30f53625415c 100644
--- a/include/video/uvesafb.h
+++ b/include/video/uvesafb.h
@@ -134,6 +134,7 @@ struct uvesafb_par {
134 134
135 int mode_idx; 135 int mode_idx;
136 struct vbe_crtc_ib crtc; 136 struct vbe_crtc_ib crtc;
137 int mtrr_handle;
137}; 138};
138 139
139#endif /* _UVESAFB_H */ 140#endif /* _UVESAFB_H */