summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@openbsd.org>2013-03-10 12:33:19 +0100
committerMark Kettenis <kettenis@openbsd.org>2013-03-10 12:33:19 +0100
commitb1361be904ba4bf7b96302b9b1b42a4fd45fc551 (patch)
tree7ab12c03a4c177c84eb2ed5de8d05576433bdfb9 /sys
parent35757ab7fa0ade9db6531574db4adb9a343df11d (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.c1
-rw-r--r--sys/dev/pci/drm/i915_drv.h8
-rw-r--r--sys/dev/pci/drm/i915_gem.c41
-rw-r--r--sys/dev/pci/drm/i915_gem_gtt.c35
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);
}