From 84f9f938be4156e4baea466688bd6abae1c9e6ba Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 12 Dec 2011 19:21:58 -0800 Subject: drm/i915: Force sync command ordering (Gen6+) The docs say this is required for Gen7, and since the bit was added for Gen6, we are also setting it there pit pf paranoia. Particularly as Chris points out, if PIPE_CONTROL counts as a 3d state packet. This was found through doc inspection by Ken and applies to Gen6+; Reported-by: Kenneth Graunke Signed-off-by: Ben Widawsky Reviewed-by: Chris Wilson Reviewed-by: Daniel Vetter Reviewed-by: Eric Anholt Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ca70e2f10445..f5dae5deca71 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -414,6 +414,11 @@ static int init_render_ring(struct intel_ring_buffer *ring) return ret; } + if (INTEL_INFO(dev)->gen >= 6) { + I915_WRITE(INSTPM, + INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); + } + return ret; } -- cgit v1.2.3-59-g8ed1b From 42ff6572e5a4a7414330a4ca91f0335da67deca9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 22 Dec 2011 14:55:00 -0800 Subject: drm/i915: Work around gen7 BLT ring synchronization issues. Previous to this commit, testing easily reproduced a failure where the seqno would apparently arrive after the IRQ associated with it, with test programs as simple as: for (;;) { glCopyPixels(0, 0, 1, 1); glFinish(); } Various workarounds we've seen for previous generations didn't work to fix this issue, so until new information comes in, replace the IRQ waits on the BLT ring with polling. Signed-off-by: Eric Anholt Tested-by: Eugeni Dodonov Reviewed-by: Eugeni Dodonov Acked-by: Kenneth Graunke Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_ringbuffer.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f5dae5deca71..d0eb2280d8d9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -791,6 +791,17 @@ ring_add_request(struct intel_ring_buffer *ring, return 0; } +static bool +gen7_blt_ring_get_irq(struct intel_ring_buffer *ring) +{ + /* The BLT ring on IVB appears to have broken synchronization + * between the seqno write and the interrupt, so that the + * interrupt appears first. Returning false here makes + * i915_wait_request() do a polling loop, instead. + */ + return false; +} + static bool gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) { @@ -1557,5 +1568,8 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) *ring = gen6_blt_ring; + if (IS_GEN7(dev)) + ring->irq_get = gen7_blt_ring_get_irq; + return intel_init_ring_buffer(dev, ring); } -- cgit v1.2.3-59-g8ed1b From e6bfaf854272ec4641a9ef7b1cb1ca963031ba95 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:56:59 +0100 Subject: drm/i915: don't bail out of intel_wait_ring_buffer too early In the pre-gem days with non-existing hangcheck and gpu reset code, this timeout of 3 seconds was pretty important to avoid stuck processes. But now we have the hangcheck code in gem that goes to great length to ensure that the gpu is really dead before declaring it wedged. So there's no need for this timeout anymore. Actually it's even harmful because we can bail out too early (e.g. with xscreensaver slip) when running giant batchbuffers. And our code isn't robust enough to properly unroll any state-changes, we pretty much rely on the gpu reset code cleaning up the mess (like cache tracking, fencing state, active list/request tracking, ...). With this change intel_begin_ring can only fail when the gpu is wedged, and it will return -EAGAIN (like wait_request in case the gpu reset is still outstanding). v2: Chris Wilson noted that on resume timers aren't running and hence we won't ever get kicked out of this loop by the hangcheck code. Use an insanely large timeout instead for the HAS_GEM case to prevent resume bugs from totally hanging the machine. Signed-off-by: Daniel Vetter Reviewed-by: Chris Wilson Acked-by: Ben Widawsky Reviewed-by: Eugeni Dodonov Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_ringbuffer.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d0eb2280d8d9..77e729d4e4f0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1135,7 +1135,16 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) } trace_i915_ring_wait_begin(ring); - end = jiffies + 3 * HZ; + if (drm_core_check_feature(dev, DRIVER_GEM)) + /* With GEM the hangcheck timer should kick us out of the loop, + * leaving it early runs the risk of corrupting GEM state (due + * to running on almost untested codepaths). But on resume + * timers don't work yet, so prevent a complete hang in that + * case by choosing an insanely large timeout. */ + end = jiffies + 60 * HZ; + else + end = jiffies + 3 * HZ; + do { ring->head = I915_READ_HEAD(ring); ring->space = ring_space(ring); -- cgit v1.2.3-59-g8ed1b