Signed-off-by: Ben Widawsky <ben at bwidawsk.net> --- drivers/gpu/drm/i915/i915_drv.h | 6 +++- drivers/gpu/drm/i915/i915_gem.c | 6 ++-- drivers/gpu/drm/i915/i915_gem_gtt.c | 56 ++++++++++++++++++------------------- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d462875..4d7990f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -369,6 +369,11 @@ struct i915_gtt_operations { int (*gmch_probe)(struct i915_gtt *gtt, size_t *gtt_total, size_t *stolen); void (*gmch_remove)(struct i915_gtt *gtt); + void (*clear_range)(struct i915_gtt *gtt, + unsigned int first_entry, + size_t num_entries); +#define unbind_object(gtt, obj) \ + clear_range(gtt, obj->gtt_space->start >> PAGE_SHIFT, obj->base.size >> PAGE_SHIFT) /* GEN6+ helpers */ size_t (*get_stolen_size)(u16 gmch_ctl); @@ -1669,7 +1674,6 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev); int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj); void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj, enum i915_cache_level cache_level); -void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj); void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj); void i915_gem_init_global_gtt(struct drm_device *dev); void i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long start, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5bb370f..66362b4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2461,8 +2461,10 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) trace_i915_gem_object_unbind(obj); - if (obj->has_global_gtt_mapping) - i915_gem_gtt_unbind_object(obj); + if (obj->has_global_gtt_mapping) { + dev_priv->gtt.gtt_ops->unbind_object(&dev_priv->gtt, obj); + obj->has_global_gtt_mapping = 0; + } if (obj->has_aliasing_ppgtt_mapping) { i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj); obj->has_aliasing_ppgtt_mapping = 0; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 2f2b1ba..5ae1d13 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -368,23 +368,20 @@ static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible) dev_priv->mm.interruptible = interruptible; } -static void i915_ggtt_clear_range(struct drm_device *dev, - unsigned first_entry, - unsigned num_entries) +static void gen6_gtt_clear_range(struct i915_gtt *gtt, + unsigned int first_entry, + size_t num_entries) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = + container_of(gtt, struct drm_i915_private, gtt); + struct drm_device *dev = dev_priv->dev; gtt_pte_t scratch_pte; gtt_pte_t __iomem *gtt_base = (gtt_pte_t __iomem *) dev_priv->gtt.gsm + first_entry; const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry; int i; - if (INTEL_INFO(dev)->gen < 6) { - intel_gtt_clear_range(first_entry, num_entries); - return; - } - if (WARN(num_entries > max_entries, - "First entry = %d; Num entries = %d (max=%d)\n", + "First entry = %d; Num entries = %zd (max=%d)\n", first_entry, num_entries, max_entries)) num_entries = max_entries; @@ -397,11 +394,12 @@ static void i915_ggtt_clear_range(struct drm_device *dev, void i915_gem_restore_gtt_mappings(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_gtt *gtt = &dev_priv->gtt; struct drm_i915_gem_object *obj; - /* First fill our portion of the GTT with scratch pages */ - i915_ggtt_clear_range(dev, dev_priv->gtt.start / PAGE_SIZE, - dev_priv->gtt.total / PAGE_SIZE); + gtt->gtt_ops->clear_range(gtt, + gtt->start >> PAGE_SHIFT, + gtt->total >> PAGE_SHIFT); list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { i915_gem_clflush_object(obj); @@ -491,15 +489,6 @@ void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj, obj->has_global_gtt_mapping = 1; } -void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) -{ - i915_ggtt_clear_range(obj->base.dev, - obj->gtt_space->start >> PAGE_SHIFT, - obj->base.size >> PAGE_SHIFT); - - obj->has_global_gtt_mapping = 0; -} - void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj) { struct drm_device *dev = obj->base.dev; @@ -542,6 +531,7 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, struct drm_mm_node *entry; struct drm_i915_gem_object *obj; unsigned long hole_start, hole_end; + struct i915_gtt *gtt = &dev_priv->gtt; BUG_ON(mappable_end > end); @@ -563,21 +553,21 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, obj->has_global_gtt_mapping = 1; } - dev_priv->gtt.start = start; - dev_priv->gtt.total = end - start; + gtt->start = start; + gtt->total = end - start; /* Clear any non-preallocated blocks */ drm_mm_for_each_hole(entry, &dev_priv->mm.gtt_space, hole_start, hole_end) { DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", hole_start, hole_end); - i915_ggtt_clear_range(dev, - hole_start / PAGE_SIZE, - (hole_end-hole_start) / PAGE_SIZE); + gtt->gtt_ops->clear_range(gtt, + hole_start / PAGE_SIZE, + (hole_end-hole_start) / PAGE_SIZE); } /* And finally clear the reserved guard page */ - i915_ggtt_clear_range(dev, end / PAGE_SIZE - 1, 1); + gtt->gtt_ops->clear_range(gtt, end / PAGE_SIZE - 1, 1); } static bool @@ -736,12 +726,14 @@ void gen6_gmch_remove(struct i915_gtt *gtt) static const struct i915_gtt_operations gen6_gtt_ops = { .gmch_probe = gen6_gmch_probe, .gmch_remove = gen6_gmch_remove, + .clear_range = gen6_gtt_clear_range, .get_stolen_size = gen6_get_stolen_size, }; static const struct i915_gtt_operations gen7_gtt_ops = { .gmch_probe = gen6_gmch_probe, .gmch_remove = gen6_gmch_remove, + .clear_range = gen6_gtt_clear_range, .get_stolen_size = gen7_get_stolen_size, }; @@ -770,9 +762,17 @@ static void i915_gmch_remove(struct i915_gtt *gtt) intel_gmch_remove(); } +static void i915_gtt_clear_range(struct i915_gtt *gtt, + unsigned int first_entry, + size_t num_entries) +{ + intel_gtt_clear_range(first_entry, num_entries); +} + static const struct i915_gtt_operations legacy_gtt_ops = { .gmch_probe = i915_gmch_probe, .gmch_remove = i915_gmch_remove, + .clear_range = i915_gtt_clear_range, }; int i915_gem_gtt_init(struct drm_device *dev) -- 1.8.1.1