diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 41 | 
1 files changed, 25 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 77e729d4e4f..1ab842c6032 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -636,6 +636,19 @@ render_ring_add_request(struct intel_ring_buffer *ring,  }  static u32 +gen6_ring_get_seqno(struct intel_ring_buffer *ring) +{ +	struct drm_device *dev = ring->dev; + +	/* Workaround to force correct ordering between irq and seqno writes on +	 * ivb (and maybe also on snb) by reading from a CS register (like +	 * ACTHD) before reading the status page. */ +	if (IS_GEN7(dev)) +		intel_ring_get_active_head(ring); +	return intel_read_status_page(ring, I915_GEM_HWS_INDEX); +} + +static u32  ring_get_seqno(struct intel_ring_buffer *ring)  {  	return intel_read_status_page(ring, I915_GEM_HWS_INDEX); @@ -792,17 +805,6 @@ 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; @@ -811,6 +813,12 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)  	if (!dev->irq_enabled)  	       return false; +	/* It looks like we need to prevent the gt from suspending while waiting +	 * for an notifiy irq, otherwise irqs seem to get lost on at least the +	 * blt/bsd rings on ivb. */ +	if (IS_GEN7(dev)) +		gen6_gt_force_wake_get(dev_priv); +  	spin_lock(&ring->irq_lock);  	if (ring->irq_refcount++ == 0) {  		ring->irq_mask &= ~rflag; @@ -835,6 +843,9 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)  		ironlake_disable_irq(dev_priv, gflag);  	}  	spin_unlock(&ring->irq_lock); + +	if (IS_GEN7(dev)) +		gen6_gt_force_wake_put(dev_priv);  }  static bool @@ -1341,7 +1352,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = {  	.write_tail		= gen6_bsd_ring_write_tail,  	.flush			= gen6_ring_flush,  	.add_request		= gen6_add_request, -	.get_seqno		= ring_get_seqno, +	.get_seqno		= gen6_ring_get_seqno,  	.irq_get		= gen6_bsd_ring_get_irq,  	.irq_put		= gen6_bsd_ring_put_irq,  	.dispatch_execbuffer	= gen6_ring_dispatch_execbuffer, @@ -1476,7 +1487,7 @@ static const struct intel_ring_buffer gen6_blt_ring = {  	.write_tail		= ring_write_tail,  	.flush			= blt_ring_flush,  	.add_request		= gen6_add_request, -	.get_seqno		= ring_get_seqno, +	.get_seqno		= gen6_ring_get_seqno,  	.irq_get		= blt_ring_get_irq,  	.irq_put		= blt_ring_put_irq,  	.dispatch_execbuffer	= gen6_ring_dispatch_execbuffer, @@ -1499,6 +1510,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)  		ring->flush = gen6_render_ring_flush;  		ring->irq_get = gen6_render_ring_get_irq;  		ring->irq_put = gen6_render_ring_put_irq; +		ring->get_seqno = gen6_ring_get_seqno;  	} else if (IS_GEN5(dev)) {  		ring->add_request = pc_render_add_request;  		ring->get_seqno = pc_render_get_seqno; @@ -1577,8 +1589,5 @@ 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);  }  |