]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
drm/agp/i915: trim stolen space to 32M
authorJesse Barnes <jbarnes@virtuousgeek.org>
Thu, 8 Jul 2010 16:22:46 +0000 (09:22 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 26 Aug 2010 23:46:17 +0000 (16:46 -0700)
commit d1d6ca73ef548748e141747e7260798327d6a2c1 upstream.

Some BIOSes will claim a large chunk of stolen space.  Unless we
reclaim it, our aperture for remapping buffer objects will be
constrained.  So clamp the stolen space to 32M and ignore the rest.

Fixes https://bugzilla.kernel.org/show_bug.cgi?id=15469 among others.

Adding the ignored stolen memory back into the general pool using the
memory hotplug code is left as an exercise for the reader.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Simon Farnsworth <simon.farnsworth@onelan.com>
Tested-by: Artem S. Tashkinov <t.artem@mailcity.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/char/agp/intel-gtt.c
drivers/gpu/drm/i915/i915_dma.c

index a7547150a705235f75f7949f89ebd99a8e3ba329..d84af6c9370e2db6a86e1017d4912a3ae60ef5bd 100644 (file)
 #define USE_PCI_DMA_API 1
 #endif
 
+/* Max amount of stolen space, anything above will be returned to Linux */
+int intel_max_stolen = 32 * 1024 * 1024;
+EXPORT_SYMBOL(intel_max_stolen);
+
 static const struct aper_size_info_fixed intel_i810_sizes[] =
 {
        {64, 16384, 4},
@@ -710,7 +714,12 @@ static void intel_i830_init_gtt_entries(void)
                        break;
                }
        }
-       if (gtt_entries > 0) {
+       if (!local && gtt_entries > intel_max_stolen) {
+               dev_info(&agp_bridge->dev->dev,
+                        "detected %dK stolen memory, trimming to %dK\n",
+                        gtt_entries / KB(1), intel_max_stolen / KB(1));
+               gtt_entries = intel_max_stolen / KB(4);
+       } else if (gtt_entries > 0) {
                dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n",
                       gtt_entries / KB(1), local ? "local" : "stolen");
                gtt_entries /= KB(4);
index 2305a1234f1e5727cf835227ff2422ed930ce097..013a0aeff709143d153eddbae484fc18c86fca52 100644 (file)
@@ -40,6 +40,8 @@
 #include <linux/vga_switcheroo.h>
 #include <linux/slab.h>
 
+extern int intel_max_stolen; /* from AGP driver */
+
 /**
  * Sets up the hardware status page for devices that need a physical address
  * in the register.
@@ -2104,6 +2106,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        if (ret)
                goto out_iomapfree;
 
+       if (prealloc_size > intel_max_stolen) {
+               DRM_INFO("detected %dM stolen memory, trimming to %dM\n",
+                        prealloc_size >> 20, intel_max_stolen >> 20);
+               prealloc_size = intel_max_stolen;
+       }
+
        dev_priv->wq = create_singlethread_workqueue("i915");
        if (dev_priv->wq == NULL) {
                DRM_ERROR("Failed to create our workqueue.\n");