diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-04-22 16:13:57 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-03 05:18:07 -0400 |
commit | c2798b19bac2538393fc932bfbe59807a4734b3e (patch) | |
tree | ee0754e4e3b8135bde45060c6df0a33dec93eab2 /drivers/gpu/drm/i915/intel_ringbuffer.c | |
parent | 1869b620d27a0e353bd6558015713fad2d0cc09b (diff) |
drm/i915: i8xx interrupt handler
gen2 hardware has some significant differences from the other interrupt
routines that were glossed over and then forgotten about in the
transition to KMS. Such as
- 16bit IIR
- PendingFlip status bit
This patch reintroduces a handler specifically for gen2 for the purpose
of handling pageflips correctly, simplifying code in the process.
v2: Also fixup ring get/put irq to only access 16bit registers (Daniel)
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=24202
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=41793
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
[danvet: use posting_read16 in intel_ringbuffer.c and kill _driver
from the function names.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 12d9bc789dfb..6249a7fa9acc 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -678,6 +678,41 @@ i9xx_ring_put_irq(struct intel_ring_buffer *ring) | |||
678 | spin_unlock(&ring->irq_lock); | 678 | spin_unlock(&ring->irq_lock); |
679 | } | 679 | } |
680 | 680 | ||
681 | static bool | ||
682 | i8xx_ring_get_irq(struct intel_ring_buffer *ring) | ||
683 | { | ||
684 | struct drm_device *dev = ring->dev; | ||
685 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
686 | |||
687 | if (!dev->irq_enabled) | ||
688 | return false; | ||
689 | |||
690 | spin_lock(&ring->irq_lock); | ||
691 | if (ring->irq_refcount++ == 0) { | ||
692 | dev_priv->irq_mask &= ~ring->irq_enable_mask; | ||
693 | I915_WRITE16(IMR, dev_priv->irq_mask); | ||
694 | POSTING_READ16(IMR); | ||
695 | } | ||
696 | spin_unlock(&ring->irq_lock); | ||
697 | |||
698 | return true; | ||
699 | } | ||
700 | |||
701 | static void | ||
702 | i8xx_ring_put_irq(struct intel_ring_buffer *ring) | ||
703 | { | ||
704 | struct drm_device *dev = ring->dev; | ||
705 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
706 | |||
707 | spin_lock(&ring->irq_lock); | ||
708 | if (--ring->irq_refcount == 0) { | ||
709 | dev_priv->irq_mask |= ring->irq_enable_mask; | ||
710 | I915_WRITE16(IMR, dev_priv->irq_mask); | ||
711 | POSTING_READ16(IMR); | ||
712 | } | ||
713 | spin_unlock(&ring->irq_lock); | ||
714 | } | ||
715 | |||
681 | void intel_ring_setup_status_page(struct intel_ring_buffer *ring) | 716 | void intel_ring_setup_status_page(struct intel_ring_buffer *ring) |
682 | { | 717 | { |
683 | struct drm_device *dev = ring->dev; | 718 | struct drm_device *dev = ring->dev; |
@@ -1310,8 +1345,13 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1310 | else | 1345 | else |
1311 | ring->flush = gen4_render_ring_flush; | 1346 | ring->flush = gen4_render_ring_flush; |
1312 | ring->get_seqno = ring_get_seqno; | 1347 | ring->get_seqno = ring_get_seqno; |
1313 | ring->irq_get = i9xx_ring_get_irq; | 1348 | if (IS_GEN2(dev)) { |
1314 | ring->irq_put = i9xx_ring_put_irq; | 1349 | ring->irq_get = i8xx_ring_get_irq; |
1350 | ring->irq_put = i8xx_ring_put_irq; | ||
1351 | } else { | ||
1352 | ring->irq_get = i9xx_ring_get_irq; | ||
1353 | ring->irq_put = i9xx_ring_put_irq; | ||
1354 | } | ||
1315 | ring->irq_enable_mask = I915_USER_INTERRUPT; | 1355 | ring->irq_enable_mask = I915_USER_INTERRUPT; |
1316 | } | 1356 | } |
1317 | ring->write_tail = ring_write_tail; | 1357 | ring->write_tail = ring_write_tail; |
@@ -1358,8 +1398,13 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) | |||
1358 | else | 1398 | else |
1359 | ring->flush = gen4_render_ring_flush; | 1399 | ring->flush = gen4_render_ring_flush; |
1360 | ring->get_seqno = ring_get_seqno; | 1400 | ring->get_seqno = ring_get_seqno; |
1361 | ring->irq_get = i9xx_ring_get_irq; | 1401 | if (IS_GEN2(dev)) { |
1362 | ring->irq_put = i9xx_ring_put_irq; | 1402 | ring->irq_get = i8xx_ring_get_irq; |
1403 | ring->irq_put = i8xx_ring_put_irq; | ||
1404 | } else { | ||
1405 | ring->irq_get = i9xx_ring_get_irq; | ||
1406 | ring->irq_put = i9xx_ring_put_irq; | ||
1407 | } | ||
1363 | ring->irq_enable_mask = I915_USER_INTERRUPT; | 1408 | ring->irq_enable_mask = I915_USER_INTERRUPT; |
1364 | ring->write_tail = ring_write_tail; | 1409 | ring->write_tail = ring_write_tail; |
1365 | if (INTEL_INFO(dev)->gen >= 4) | 1410 | if (INTEL_INFO(dev)->gen >= 4) |