diff options
author | Thomas Hellstrom <thomas@tungstengraphics.com> | 2006-05-26 16:44:58 +0000 |
---|---|---|
committer | Thomas Hellstrom <thomas@tungstengraphics.com> | 2006-05-26 16:44:58 +0000 |
commit | 04797f75c5413abac35f3cbb297d75d27b48e866 (patch) | |
tree | 00c9962188e0d6f77b53d1e41c16ffe108fa5526 | |
parent | ef87f0dca8a87b21e7dc5a6a48f90d313ce5baf2 (diff) |
i915: Only enable user IRQs when we actually wait for them.
-rw-r--r-- | shared-core/i915_drv.h | 4 | ||||
-rw-r--r-- | shared-core/i915_irq.c | 33 |
2 files changed, 36 insertions, 1 deletions
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 55d60f4c..81f3b2ae 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -92,6 +92,10 @@ typedef struct drm_i915_private { wait_queue_head_t irq_queue; atomic_t irq_received; atomic_t irq_emitted; + + int user_irq_refcount; + spinlock_t user_irq_lock; + uint32_t irq_enable_reg; int tex_lru_log_granularity; int allow_batchbuffer; diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 72cdbeb0..e3367f39 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -86,6 +86,31 @@ static int i915_emit_irq(drm_device_t * dev) return ret; } + + +static void i915_user_irq_on(drm_i915_private_t *dev_priv) +{ + + spin_lock(&dev_priv->user_irq_lock); + if (++dev_priv->user_irq_refcount > 0){ + dev_priv->irq_enable_reg |= USER_INT_FLAG; + I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + } + spin_unlock(&dev_priv->user_irq_lock); + +} + +static void i915_user_irq_off(drm_i915_private_t *dev_priv) +{ + spin_lock(&dev_priv->user_irq_lock); + if (--dev_priv->user_irq_refcount == 0) { + dev_priv->irq_enable_reg &= ~USER_INT_FLAG; + I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + } + spin_unlock(&dev_priv->user_irq_lock); +} + + static int i915_wait_irq(drm_device_t * dev, int irq_nr) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -100,8 +125,10 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr) dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; + i915_user_irq_on(dev_priv); DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, (((uint32_t)(READ_BREADCRUMB(dev_priv) - irq_nr)) <= (1 << 23))); + i915_user_irq_off(dev_priv); if (ret == DRM_ERR(EBUSY)) { DRM_ERROR("%s: EBUSY -- rec: %d emitted: %d\n", @@ -161,6 +188,7 @@ int i915_irq_emit(DRM_IOCTL_ARGS) return 0; } + /* Doesn't need the hardware lock. */ int i915_irq_wait(DRM_IOCTL_ARGS) @@ -195,7 +223,10 @@ void i915_driver_irq_postinstall(drm_device_t * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | VSYNC_PIPEA_FLAG); + dev_priv->irq_enable_reg = VSYNC_PIPEA_FLAG; + dev_priv->user_irq_lock = SPIN_LOCK_UNLOCKED; + dev_priv->user_irq_refcount = 0; + I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); } |