drm/i915,agp/intel: Do not clear stolen entries
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 21 Jan 2011 10:54:32 +0000 (10:54 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 24 Jan 2011 18:26:25 +0000 (18:26 +0000)
We can only utilize the stolen portion of the GTT if we are in sole
charge of the hardware. This is only true if using GEM and KMS,
otherwise VESA continues to access stolen memory.

Reported-by: Arnd Bergmann <arnd@arndb.de>
Reported-by: Frederic Weisbecker <fweisbec@gmail.com>
Tested-by: Jiri Olsa <jolsa@redhat.com>
Tested-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/char/agp/intel-gtt.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_gtt.c

index 826ab0939a128308b294207eda495207884f5361..fab3d3265adbec77ba71096587d924e9858d59f7 100644 (file)
@@ -68,6 +68,7 @@ static struct _intel_private {
        phys_addr_t gma_bus_addr;
        u32 PGETBL_save;
        u32 __iomem *gtt;               /* I915G */
+       bool clear_fake_agp; /* on first access via agp, fill with scratch */
        int num_dcache_entries;
        union {
                void __iomem *i9xx_flush_page;
@@ -869,21 +870,12 @@ static int intel_fake_agp_free_gatt_table(struct agp_bridge_data *bridge)
 
 static int intel_fake_agp_configure(void)
 {
-       int i;
-
        if (!intel_enable_gtt())
            return -EIO;
 
+       intel_private.clear_fake_agp = true;
        agp_bridge->gart_bus_addr = intel_private.gma_bus_addr;
 
-       for (i = 0; i < intel_private.base.gtt_total_entries; i++) {
-               intel_private.driver->write_entry(intel_private.scratch_page_dma,
-                                                 i, 0);
-       }
-       readl(intel_private.gtt+i-1);   /* PCI Posting. */
-
-       global_cache_flush();
-
        return 0;
 }
 
@@ -945,6 +937,13 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
 {
        int ret = -EINVAL;
 
+       if (intel_private.clear_fake_agp) {
+               int start = intel_private.base.stolen_size / PAGE_SIZE;
+               int end = intel_private.base.gtt_mappable_entries;
+               intel_gtt_clear_range(start, end - start);
+               intel_private.clear_fake_agp = false;
+       }
+
        if (INTEL_GTT_GEN == 1 && type == AGP_DCACHE_MEMORY)
                return i810_insert_dcache_entries(mem, pg_start, type);
 
index 5969f46ac2d6023740204c74e62d25265cfc736f..a0149c619cdd117026f2c4f32309ee462b623455 100644 (file)
@@ -543,8 +543,11 @@ typedef struct drm_i915_private {
                /** List of all objects in gtt_space. Used to restore gtt
                 * mappings on resume */
                struct list_head gtt_list;
-               /** End of mappable part of GTT */
+
+               /** Usable portion of the GTT for GEM */
+               unsigned long gtt_start;
                unsigned long gtt_mappable_end;
+               unsigned long gtt_end;
 
                struct io_mapping *gtt_mapping;
                int gtt_mtrr;
index 812b97b47469cd2aa92bf651994b8c305ad0f141..cf4f74c7c6fb6fb7fa8dcedc4839ce2910039846 100644 (file)
@@ -140,12 +140,16 @@ void i915_gem_do_init(struct drm_device *dev,
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
 
-       drm_mm_init(&dev_priv->mm.gtt_space, start,
-                   end - start);
+       drm_mm_init(&dev_priv->mm.gtt_space, start, end - start);
 
+       dev_priv->mm.gtt_start = start;
+       dev_priv->mm.gtt_mappable_end = mappable_end;
+       dev_priv->mm.gtt_end = end;
        dev_priv->mm.gtt_total = end - start;
        dev_priv->mm.mappable_gtt_total = min(end, mappable_end) - start;
-       dev_priv->mm.gtt_mappable_end = mappable_end;
+
+       /* Take over this portion of the GTT */
+       intel_gtt_clear_range(start / PAGE_SIZE, (end-start) / PAGE_SIZE);
 }
 
 int
index 70433ae50ac80fe4fe44f90be74c4cb5840c3715..b0abdc64aa9f63aba4b018626da562421deb2a84 100644 (file)
@@ -34,6 +34,10 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj;
 
+       /* First fill our portion of the GTT with scratch pages */
+       intel_gtt_clear_range(dev_priv->mm.gtt_start / PAGE_SIZE,
+                             (dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE);
+
        list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
                i915_gem_clflush_object(obj);