Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

video: fbdev: tdfxfb: use arch_phys_wc_add() and ioremap_wc()

This driver uses the same area for MTRR as for the ioremap().
Convert the driver from using the x86 specific MTRR code to
the architecture agnostic arch_phys_wc_add(). arch_phys_wc_add()
will avoid MTRR if write-combining is available, in order to
take advantage of that also ensure the ioremap'd area is requested
as write-combining.

There are a few motivations for this:

a) Take advantage of PAT when available

b) Help bury MTRR code away, MTRR is architecture specific and on
x86 its replaced by PAT

c) Help with the goal of eventually using _PAGE_CACHE_UC over
_PAGE_CACHE_UC_MINUS on x86 on ioremap_nocache() (see commit
de33c442e titled "x86 PAT: fix performance drop for glx,
use UC minus for ioremap(), ioremap_nocache() and
pci_mmap_page_range()")

The conversion done is expressed by the following Coccinelle
SmPL patch, it additionally required manual intervention to
address all the #ifdery and removal of redundant things which
arch_phys_wc_add() already addresses such as verbose message
about when MTRR fails and doing nothing when we didn't get
an MTRR.

@ mtrr_found @
expression index, base, size;
@@

-index = mtrr_add(base, size, MTRR_TYPE_WRCOMB, 1);
+index = arch_phys_wc_add(base, size);

@ mtrr_rm depends on mtrr_found @
expression mtrr_found.index, mtrr_found.base, mtrr_found.size;
@@

-mtrr_del(index, base, size);
+arch_phys_wc_del(index);

@ mtrr_rm_zero_arg depends on mtrr_found @
expression mtrr_found.index;
@@

-mtrr_del(index, 0, 0);
+arch_phys_wc_del(index);

@ mtrr_rm_fb_info depends on mtrr_found @
struct fb_info *info;
expression mtrr_found.index;
@@

-mtrr_del(index, info->fix.smem_start, info->fix.smem_len);
+arch_phys_wc_del(index);

@ ioremap_replace_nocache depends on mtrr_found @
struct fb_info *info;
expression base, size;
@@

-info->screen_base = ioremap_nocache(base, size);
+info->screen_base = ioremap_wc(base, size);

@ ioremap_replace_default depends on mtrr_found @
struct fb_info *info;
expression base, size;
@@

-info->screen_base = ioremap(base, size);
+info->screen_base = ioremap_wc(base, size);

Generated-by: Coccinelle SmPL
Cc: Rob Clark <robdclark@gmail.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Suresh Siddha <sbsiddha@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Juergen Gross <jgross@suse.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Antonino Daplas <adaplas@gmail.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

authored by

Luis R. Rodriguez and committed by
Tomi Valkeinen
cc9866eb 04dc78b4

+7 -36
+6 -35
drivers/video/fbdev/tdfxfb.c
··· 78 78 79 79 #define DPRINTK(a, b...) pr_debug("fb: %s: " a, __func__ , ## b) 80 80 81 - #ifdef CONFIG_MTRR 82 - #include <asm/mtrr.h> 83 - #else 84 - /* duplicate asm/mtrr.h defines to work on archs without mtrr */ 85 - #define MTRR_TYPE_WRCOMB 1 86 - 87 - static inline int mtrr_add(unsigned long base, unsigned long size, 88 - unsigned int type, char increment) 89 - { 90 - return -ENODEV; 91 - } 92 - static inline int mtrr_del(int reg, unsigned long base, 93 - unsigned long size) 94 - { 95 - return -ENODEV; 96 - } 97 - #endif 98 - 99 81 #define BANSHEE_MAX_PIXCLOCK 270000 100 82 #define VOODOO3_MAX_PIXCLOCK 300000 101 83 #define VOODOO5_MAX_PIXCLOCK 350000 ··· 149 167 static int nowrap = 1; /* not implemented (yet) */ 150 168 static int hwcursor = 1; 151 169 static char *mode_option; 152 - /* mtrr option */ 153 170 static bool nomtrr; 154 171 155 172 /* ------------------------------------------------------------------------- ··· 1435 1454 goto out_err_regbase; 1436 1455 } 1437 1456 1438 - info->screen_base = ioremap_nocache(info->fix.smem_start, 1439 - info->fix.smem_len); 1457 + info->screen_base = ioremap_wc(info->fix.smem_start, 1458 + info->fix.smem_len); 1440 1459 if (!info->screen_base) { 1441 1460 printk(KERN_ERR "fb: Can't remap %s framebuffer.\n", 1442 1461 info->fix.id); ··· 1454 1473 printk(KERN_INFO "fb: %s memory = %dK\n", info->fix.id, 1455 1474 info->fix.smem_len >> 10); 1456 1475 1457 - default_par->mtrr_handle = -1; 1458 1476 if (!nomtrr) 1459 - default_par->mtrr_handle = 1460 - mtrr_add(info->fix.smem_start, info->fix.smem_len, 1461 - MTRR_TYPE_WRCOMB, 1); 1477 + default_par->wc_cookie= arch_phys_wc_add(info->fix.smem_start, 1478 + info->fix.smem_len); 1462 1479 1463 1480 info->fix.ypanstep = nopan ? 0 : 1; 1464 1481 info->fix.ywrapstep = nowrap ? 0 : 1; ··· 1545 1566 #ifdef CONFIG_FB_3DFX_I2C 1546 1567 tdfxfb_delete_i2c_busses(default_par); 1547 1568 #endif 1548 - if (default_par->mtrr_handle >= 0) 1549 - mtrr_del(default_par->mtrr_handle, info->fix.smem_start, 1550 - info->fix.smem_len); 1569 + arch_phys_wc_del(default_par->wc_cookie); 1551 1570 release_region(pci_resource_start(pdev, 2), 1552 1571 pci_resource_len(pdev, 2)); 1553 1572 out_err_screenbase: ··· 1581 1604 nowrap = 1; 1582 1605 } else if (!strncmp(this_opt, "hwcursor=", 9)) { 1583 1606 hwcursor = simple_strtoul(this_opt + 9, NULL, 0); 1584 - #ifdef CONFIG_MTRR 1585 1607 } else if (!strncmp(this_opt, "nomtrr", 6)) { 1586 1608 nomtrr = 1; 1587 - #endif 1588 1609 } else { 1589 1610 mode_option = this_opt; 1590 1611 } ··· 1608 1633 #ifdef CONFIG_FB_3DFX_I2C 1609 1634 tdfxfb_delete_i2c_busses(par); 1610 1635 #endif 1611 - if (par->mtrr_handle >= 0) 1612 - mtrr_del(par->mtrr_handle, info->fix.smem_start, 1613 - info->fix.smem_len); 1636 + arch_phys_wc_del(par->wc_cookie); 1614 1637 iounmap(par->regbase_virt); 1615 1638 iounmap(info->screen_base); 1616 1639 ··· 1650 1677 "(1=enable, 0=disable, default=1)"); 1651 1678 module_param(mode_option, charp, 0); 1652 1679 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'"); 1653 - #ifdef CONFIG_MTRR 1654 1680 module_param(nomtrr, bool, 0); 1655 1681 MODULE_PARM_DESC(nomtrr, "Disable MTRR support (default: enabled)"); 1656 - #endif 1657 1682 1658 1683 module_init(tdfxfb_init); 1659 1684 module_exit(tdfxfb_exit);
+1 -1
include/video/tdfx.h
··· 196 196 u32 palette[16]; 197 197 void __iomem *regbase_virt; 198 198 unsigned long iobase; 199 - int mtrr_handle; 199 + int wc_cookie; 200 200 #ifdef CONFIG_FB_3DFX_I2C 201 201 struct tdfxfb_i2c_chan chan[2]; 202 202 #endif