aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h9
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c63
2 files changed, 50 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b3bfab93e14c..dc371d987aa7 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -791,12 +791,15 @@ struct drm_i915_gem_object {
791 unsigned int fault_mappable : 1; 791 unsigned int fault_mappable : 1;
792 unsigned int pin_mappable : 1; 792 unsigned int pin_mappable : 1;
793 793
794 /** AGP memory structure for our GTT binding. */
795 DRM_AGP_MEM *agp_mem;
796
797 struct page **pages; 794 struct page **pages;
798 795
799 /** 796 /**
797 * DMAR support
798 */
799 struct scatterlist *sg_list;
800 int num_sg;
801
802 /**
800 * Current offset of the object in GTT space. 803 * Current offset of the object in GTT space.
801 * 804 *
802 * This is the same as gtt_space->start 805 * This is the same as gtt_space->start
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f78c15f9e7f2..0b34a1aee9b6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -33,15 +33,24 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
33{ 33{
34 struct drm_i915_private *dev_priv = dev->dev_private; 34 struct drm_i915_private *dev_priv = dev->dev_private;
35 struct drm_i915_gem_object *obj_priv; 35 struct drm_i915_gem_object *obj_priv;
36 int ret;
37 36
38 list_for_each_entry(obj_priv, 37 list_for_each_entry(obj_priv,
39 &dev_priv->mm.gtt_list, 38 &dev_priv->mm.gtt_list,
40 gtt_list) { 39 gtt_list) {
41 /* Hack to force agp to reinsert buffer object. */ 40 if (dev_priv->mm.gtt->needs_dmar) {
42 obj_priv->agp_mem->is_bound = false; 41 BUG_ON(!obj_priv->sg_list);
43 ret = agp_bind_memory(obj_priv->agp_mem, obj_priv->gtt_space->start / PAGE_SIZE); 42
44 BUG_ON(ret != 0); 43 intel_gtt_insert_sg_entries(obj_priv->sg_list,
44 obj_priv->num_sg,
45 obj_priv->gtt_space->start
46 >> PAGE_SHIFT,
47 obj_priv->agp_type);
48 } else
49 intel_gtt_insert_pages(obj_priv->gtt_space->start
50 >> PAGE_SHIFT,
51 obj_priv->base.size >> PAGE_SHIFT,
52 obj_priv->pages,
53 obj_priv->agp_type);
45 } 54 }
46 55
47 /* Be paranoid and flush the chipset cache. */ 56 /* Be paranoid and flush the chipset cache. */
@@ -51,27 +60,43 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
51int i915_gem_gtt_bind_object(struct drm_gem_object *obj) 60int i915_gem_gtt_bind_object(struct drm_gem_object *obj)
52{ 61{
53 struct drm_device *dev = obj->dev; 62 struct drm_device *dev = obj->dev;
63 struct drm_i915_private *dev_priv = dev->dev_private;
54 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 64 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
65 int ret;
55 66
56 /* Create an AGP memory structure pointing at our pages, and bind it 67 if (dev_priv->mm.gtt->needs_dmar) {
57 * into the GTT. 68 ret = intel_gtt_map_memory(obj_priv->pages,
58 */ 69 obj->size >> PAGE_SHIFT,
59 obj_priv->agp_mem = drm_agp_bind_pages(dev, 70 &obj_priv->sg_list,
60 obj_priv->pages, 71 &obj_priv->num_sg);
61 obj->size >> PAGE_SHIFT, 72 if (ret != 0)
62 obj_priv->gtt_space->start, 73 return ret;
63 obj_priv->agp_type); 74
75 intel_gtt_insert_sg_entries(obj_priv->sg_list, obj_priv->num_sg,
76 obj_priv->gtt_space->start
77 >> PAGE_SHIFT,
78 obj_priv->agp_type);
79 } else
80 intel_gtt_insert_pages(obj_priv->gtt_space->start >> PAGE_SHIFT,
81 obj->size >> PAGE_SHIFT,
82 obj_priv->pages,
83 obj_priv->agp_type);
64 84
65 if (obj_priv->agp_mem) 85 return 0;
66 return 0;
67 else
68 return -ENOMEM;
69} 86}
70 87
71void i915_gem_gtt_unbind_object(struct drm_gem_object *obj) 88void i915_gem_gtt_unbind_object(struct drm_gem_object *obj)
72{ 89{
90 struct drm_device *dev = obj->dev;
91 struct drm_i915_private *dev_priv = dev->dev_private;
73 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 92 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
74 93
75 drm_unbind_agp(obj_priv->agp_mem); 94 if (dev_priv->mm.gtt->needs_dmar) {
76 drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); 95 intel_gtt_unmap_memory(obj_priv->sg_list, obj_priv->num_sg);
96 obj_priv->sg_list = NULL;
97 obj_priv->num_sg = 0;
98 }
99
100 intel_gtt_clear_range(obj_priv->gtt_space->start >> PAGE_SHIFT,
101 obj->size >> PAGE_SHIFT);
77} 102}