mtrr: only add prefetchable resources as WRCOMB for VGA devices

Be more conservative and only add VGA devices' prefetchable
resources as write-combining in the address space. Previously
all prefetchable memory was added as a write-combining memory
type. Some hardware incorrectly advertises its BAR as
prefetchable when it shouldn't be.

A new memranges_add_resources_filter() function is added
to provide additional filtering on device and resource.

Change-Id: I3fc55b90d8c5b694c5aa9e2f34db1b4ef845ce10
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/5169
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
Tested-by: build bot (Jenkins)
diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c
index dfb9c94..d85a869 100644
--- a/src/cpu/x86/mtrr/mtrr.c
+++ b/src/cpu/x86/mtrr/mtrr.c
@@ -30,6 +30,7 @@
 #include <bootstate.h>
 #include <console/console.h>
 #include <device/device.h>
+#include <device/pci_ids.h>
 #include <cpu/cpu.h>
 #include <cpu/x86/msr.h>
 #include <cpu/x86/mtrr.h>
@@ -154,6 +155,20 @@
 	return range_entry_tag(r) & MTRR_TAG_MASK;
 }
 
+static int filter_vga_wrcomb(struct device *dev, struct resource *res)
+{
+	/* Only handle PCI devices. */
+	if (dev->path.type != DEVICE_PATH_PCI)
+		return 0;
+
+	/* Only handle VGA class devices. */
+	if (((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA))
+		return 0;
+
+	/* Add resource as write-combining in the address space. */
+	return 1;
+}
+
 static struct memranges *get_physical_address_space(void)
 {
 	static struct memranges *addr_space;
@@ -181,8 +196,8 @@
 		 * resources are appropriate for this MTRR type. */
 		match = IORESOURCE_PREFETCH;
 		mask |= match;
-		memranges_add_resources(addr_space, mask, match,
-		                        MTRR_TYPE_WRCOMB);
+		memranges_add_resources_filter(addr_space, mask, match, MTRR_TYPE_WRCOMB,
+		                               filter_vga_wrcomb);
 
 #if CONFIG_CACHE_ROM
 		/* Add a write-protect region covering the ROM size