diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 63 |
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) | |||
51 | int i915_gem_gtt_bind_object(struct drm_gem_object *obj) | 60 | int 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 | ||
71 | void i915_gem_gtt_unbind_object(struct drm_gem_object *obj) | 88 | void 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 | } |