diff options
author | Mark Kettenis <kettenis@openbsd.org> | 2013-03-10 12:33:19 +0100 |
---|---|---|
committer | Mark Kettenis <kettenis@openbsd.org> | 2013-03-10 12:33:19 +0100 |
commit | b1361be904ba4bf7b96302b9b1b42a4fd45fc551 (patch) | |
tree | 7ab12c03a4c177c84eb2ed5de8d05576433bdfb9 /sys | |
parent | 35757ab7fa0ade9db6531574db4adb9a343df11d (diff) |
Make i915_gem_gtt_rebind_object() less stupid and move it into i915_gem_gtt.c.
Use it to properly implement i915_gem_resetore_gtt_mappings().
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/drm/i915_drv.c | 1 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_drv.h | 8 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_gem.c | 41 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_gem_gtt.c | 35 |
4 files changed, 49 insertions, 36 deletions
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c index fa0bc910edc..113d5f755b1 100644 --- a/sys/dev/pci/drm/i915_drv.c +++ b/sys/dev/pci/drm/i915_drv.c @@ -992,6 +992,7 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) /* GEM init */ INIT_LIST_HEAD(&dev_priv->mm.active_list); INIT_LIST_HEAD(&dev_priv->mm.inactive_list); + INIT_LIST_HEAD(&dev_priv->mm.bound_list); INIT_LIST_HEAD(&dev_priv->mm.fence_list); for (i = 0; i < I915_NUM_RINGS; i++) init_ring_lists(&dev_priv->rings[i]); diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h index 16b3d9fe2d2..cd0433220a1 100644 --- a/sys/dev/pci/drm/i915_drv.h +++ b/sys/dev/pci/drm/i915_drv.h @@ -639,6 +639,10 @@ struct inteldrm_softc { bool modeset_on_lid; struct { + /** List of all objects in gtt_space. Used to restore gtt + * mappings on resume */ + struct list_head bound_list; + /** * List of objects currently involved in rendering from the * ringbuffer. @@ -847,6 +851,8 @@ struct inteldrm_file { struct drm_i915_gem_object { struct drm_obj base; + struct list_head gtt_list; + /** This object's place on the active/flushing/inactive lists */ struct list_head ring_list; struct list_head mm_list; @@ -1217,6 +1223,8 @@ extern void opregion_enable_asle(struct drm_device *dev); /* i915_gem_gtt.c */ void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev); void i915_gem_restore_gtt_mappings(struct drm_device *dev); +void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj, + enum i915_cache_level); /* modesetting */ extern void intel_modeset_init_hw(struct drm_device *dev); diff --git a/sys/dev/pci/drm/i915_gem.c b/sys/dev/pci/drm/i915_gem.c index f94ac203992..ff19049fa48 100644 --- a/sys/dev/pci/drm/i915_gem.c +++ b/sys/dev/pci/drm/i915_gem.c @@ -71,8 +71,6 @@ struct drm_i915_fence_reg *i915_find_fence_reg(struct drm_device *); void i915_gem_reset_ring_lists(drm_i915_private_t *, struct intel_ring_buffer *); void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *); -int i915_gem_gtt_rebind_object(struct drm_i915_gem_object *, - enum i915_cache_level); void i915_gem_request_remove_from_client(struct drm_i915_gem_request *); int i915_gem_object_flush_active(struct drm_i915_gem_object *); int i915_gem_check_olr(struct intel_ring_buffer *, u32); @@ -1428,13 +1426,13 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) /* XXX this should change whether we tell uvm the page is dirty */ obj->dirty = 0; + list_del_init(&obj->gtt_list); + list_del_init(&obj->mm_list); + obj->gtt_offset = 0; atomic_dec(&dev->gtt_count); atomic_sub(obj->base.size, &dev->gtt_memory); - /* Remove ourselves from any LRU list if present. */ - list_del_init(&obj->mm_list); - if (i915_gem_object_is_purgeable(obj)) inteldrm_purge_obj(&obj->base); @@ -1775,36 +1773,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj) // i915_gem_valid_gtt_space // i915_gem_verify_gtt -/* XXX make this less stupid */ -int -i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj, - enum i915_cache_level cache_level) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - /* - * unload the map, then unwire the backing object. - */ - i915_gem_object_save_bit_17_swizzle(obj); - bus_dmamap_unload(dev_priv->agpdmat, obj->dmamap); - uvm_objunwire(obj->base.uao, 0, obj->base.size); - /* XXX persistent dmamap worth the memory? */ - bus_dmamap_destroy(dev_priv->agpdmat, obj->dmamap); - obj->dmamap = NULL; - free(obj->dma_segs, M_DRM); - obj->dma_segs = NULL; - /* XXX this should change whether we tell uvm the page is dirty */ - obj->dirty = 0; - - obj->gtt_offset = 0; - atomic_dec(&dev->gtt_count); - atomic_sub(obj->base.size, &dev->gtt_memory); - - obj->cache_level = cache_level; - return (i915_gem_object_bind_to_gtt(obj, 0)); -} - /** * Finds free space in the GTT aperture and binds the object there. */ @@ -1879,6 +1847,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, } i915_gem_object_save_bit_17_swizzle(obj); + list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list); + obj->gtt_offset = obj->dmamap->dm_segs[0].ds_addr - dev->agp->base; atomic_inc(&dev->gtt_count); @@ -2613,6 +2583,7 @@ i915_gem_init_object(struct drm_obj *obj) obj_priv->map_and_fenceable = true; INIT_LIST_HEAD(&obj_priv->mm_list); + INIT_LIST_HEAD(&obj_priv->gtt_list); INIT_LIST_HEAD(&obj_priv->ring_list); return 0; diff --git a/sys/dev/pci/drm/i915_gem_gtt.c b/sys/dev/pci/drm/i915_gem_gtt.c index 21e0a672e29..0973ec423b1 100644 --- a/sys/dev/pci/drm/i915_gem_gtt.c +++ b/sys/dev/pci/drm/i915_gem_gtt.c @@ -12,5 +12,38 @@ i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev) void i915_gem_restore_gtt_mappings(struct drm_device *dev) { - /* Nothing to be done on OpenBSD */ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj; + + list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { + i915_gem_clflush_object(obj); + i915_gem_gtt_rebind_object(obj, obj->cache_level); + } + + i915_gem_chipset_flush(dev); +} + +void +i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj, + enum i915_cache_level cache_level) +{ + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; + int flags = obj->dma_flags; + + switch (cache_level) { + case I915_CACHE_NONE: + flags |= BUS_DMA_GTT_NOCACHE; + break; + case I915_CACHE_LLC: + flags |= BUS_DMA_GTT_CACHE_LLC; + break; + case I915_CACHE_LLC_MLC: + flags |= BUS_DMA_GTT_CACHE_LLC_MLC; + break; + default: + BUG(); + } + + agp_bus_dma_rebind(dev_priv->agpdmat, obj->dmamap, flags); } |