diff options
author | Eric Anholt <eric@anholt.net> | 2011-12-22 14:55:00 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2012-01-03 09:31:15 -0800 |
commit | 42ff6572e5a4a7414330a4ca91f0335da67deca9 (patch) | |
tree | dc8937a9bd595065cd73cd51a4baab365a96813b /drivers | |
parent | 7ea29b13e5e3e1e61e612349eb0366efdb6457f3 (diff) | |
download | linux-42ff6572e5a4a7414330a4ca91f0335da67deca9.tar.gz linux-42ff6572e5a4a7414330a4ca91f0335da67deca9.tar.bz2 linux-42ff6572e5a4a7414330a4ca91f0335da67deca9.zip |
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 <eric@anholt.net>
Tested-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Acked-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 14 |
1 files changed, 14 insertions, 0 deletions
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 @@ -792,6 +792,17 @@ ring_add_request(struct intel_ring_buffer *ring, } 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) { struct drm_device *dev = ring->dev; @@ -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); } |