summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJonathan Gray <jsg@jsg.id.au>2013-03-06 11:18:38 +1100
committerJonathan Gray <jsg@jsg.id.au>2013-03-06 11:18:38 +1100
commit237542d8c998c9d93ab705bd8145acc8d4173c8a (patch)
tree556bbec90cc5f7cb076663052d1f822b40ad4381 /sys/dev
parent160d380656cc1cca12e0a27340f30a429b9c7e2d (diff)
enable using gpu semaphores for ring sync
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/drm/i915_drv.c3
-rw-r--r--sys/dev/pci/drm/i915_drv.h1
-rw-r--r--sys/dev/pci/drm/i915_gem.c5
-rw-r--r--sys/dev/pci/drm/i915_gem_execbuffer.c40
4 files changed, 30 insertions, 19 deletions
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c
index c720b3869a6..c0b13ffce2e 100644
--- a/sys/dev/pci/drm/i915_drv.c
+++ b/sys/dev/pci/drm/i915_drv.c
@@ -71,6 +71,9 @@ int i915_panel_ignore_lid = 1;
/* Enable powersavings, fbc, downclocking, etc. (default: true) */
unsigned int i915_powersave = 1;
+/* Use semaphores for inter-ring sync (default: -1 (use per-chip defaults)) */
+int i915_semaphores = -1;
+
/*
* Enable frame buffer compression for power savings
* (default: -1 (use per-chip default))
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index 40665eab1a6..60efe11849d 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -1501,6 +1501,7 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
extern unsigned int i915_lvds_downclock;
extern int i915_panel_ignore_lid;
extern unsigned int i915_powersave;
+extern int i915_semaphores;
extern int i915_enable_rc6;
extern int i915_enable_fbc;
diff --git a/sys/dev/pci/drm/i915_gem.c b/sys/dev/pci/drm/i915_gem.c
index ef0db7eb69f..3f78da803c6 100644
--- a/sys/dev/pci/drm/i915_gem.c
+++ b/sys/dev/pci/drm/i915_gem.c
@@ -1195,12 +1195,17 @@ void
i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
{
uint32_t seqno;
+ int i;
if (list_empty(&ring->request_list))
return;
seqno = ring->get_seqno(ring, true);
+ for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++)
+ if (seqno >= ring->sync_seqno[i])
+ ring->sync_seqno[i] = 0;
+
while (!list_empty(&ring->request_list)) {
struct drm_i915_gem_request *request;
diff --git a/sys/dev/pci/drm/i915_gem_execbuffer.c b/sys/dev/pci/drm/i915_gem_execbuffer.c
index 6cc802de500..823aed23018 100644
--- a/sys/dev/pci/drm/i915_gem_execbuffer.c
+++ b/sys/dev/pci/drm/i915_gem_execbuffer.c
@@ -297,8 +297,6 @@ i915_gem_execbuffer_flush(struct drm_device *dev,
bool
intel_enable_semaphores(struct drm_device *dev)
{
- return 0;
-#ifdef notyet
if (INTEL_INFO(dev)->gen < 6)
return 0;
@@ -310,7 +308,6 @@ intel_enable_semaphores(struct drm_device *dev)
return 0;
return 1;
-#endif
}
int
@@ -318,42 +315,31 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj,
struct intel_ring_buffer *to)
{
struct intel_ring_buffer *from = obj->ring;
-// u32 seqno;
-// int ret, idx;
+ u32 seqno;
+ int ret, idx;
if (from == NULL || to == from)
return 0;
/* XXX gpu semaphores are implicated in various hard hangs on SNB */
-// if (!intel_enable_semaphores(obj->base.dev))
+ if (!intel_enable_semaphores(obj->base.dev))
return i915_gem_object_wait_rendering(obj, false);
-#ifdef notyet
idx = intel_ring_sync_index(from, to);
- seqno = obj->last_rendering_seqno;
+ seqno = obj->last_read_seqno;
if (seqno <= from->sync_seqno[idx])
return 0;
if (seqno == from->outstanding_lazy_request) {
- struct drm_i915_gem_request *request;
-
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
- ret = i915_add_request(from, NULL, request);
+ ret = i915_add_request(from, NULL, &seqno);
if (ret) {
- kfree(request);
return ret;
}
-
- seqno = request->seqno;
}
from->sync_seqno[idx] = seqno;
return to->sync_to(to, from, seqno - 1);
-#endif
}
int
@@ -532,6 +518,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
int ret, ret2, i;
int pinned = 0, pin_tries;
uint32_t reloc_index;
+ uint32_t seqno;
/*
* Check for valid execbuffer offset. We can do this early because
@@ -691,6 +678,21 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
if (ret)
goto err;
+ seqno = i915_gem_next_request_seqno(ring);
+ for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) {
+ if (seqno < ring->sync_seqno[i]) {
+ /* The GPU can not handle its semaphore value wrapping,
+ * so every billion or so execbuffers, we need to stall
+ * the GPU in order to reset the counters.
+ */
+ ret = i915_gpu_idle(dev);
+ if (ret)
+ goto err;
+
+ BUG_ON(ring->sync_seqno[i]);
+ }
+ }
+
if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
ret = i915_reset_gen7_sol_offsets(dev, ring);
if (ret)