diff options
-rw-r--r-- | shared-core/i915_drv.h | 2 | ||||
-rw-r--r-- | shared-core/i915_irq.c | 126 |
2 files changed, 35 insertions, 93 deletions
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index a8d5b91e..0df5af9c 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -129,8 +129,6 @@ typedef struct drm_i915_private { int user_irq_refcount; int fence_irq_on; uint32_t irq_mask_reg; - uint32_t irq_enable_reg; - int irq_use_mask; int irq_enabled; #ifdef I915_HAVE_FENCE diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index f9fed87e..a55497a8 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -40,63 +40,6 @@ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) -static inline void -i915_enable_irq(drm_i915_private_t *dev_priv, uint32_t mask) -{ - if (dev_priv->irq_use_mask) { - if ((dev_priv->irq_mask_reg & mask) != 0) { - dev_priv->irq_mask_reg &= ~mask; - I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); - (void) I915_READ(I915REG_INT_MASK_R); - } - } else { - if ((dev_priv->irq_enable_reg & mask) != mask) { - dev_priv->irq_enable_reg |= mask; - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); - (void) I915_READ(I915REG_INT_ENABLE_R); - } - } -} - -static inline void -i915_disable_irq(drm_i915_private_t *dev_priv, uint32_t mask) -{ - if (dev_priv->irq_use_mask) { - if ((dev_priv->irq_mask_reg & mask) != mask) { - dev_priv->irq_mask_reg |= mask; - I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); - (void) I915_READ(I915REG_INT_MASK_R); - } - } else { - if ((dev_priv->irq_enable_reg & mask) != 0) { - dev_priv->irq_enable_reg &= ~mask; - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); - (void) I915_READ(I915REG_INT_ENABLE_R); - } - } -} - -static inline void -i915_enable_irqs(drm_i915_private_t *dev_priv) -{ - if (dev_priv->irq_use_mask) { - I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); - (void) I915_READ(I915REG_INT_MASK_R); - } else { - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); - (void) I915_READ(I915REG_INT_ENABLE_R); - } -} - -static inline void -i915_disable_irqs(drm_i915_private_t *dev_priv) -{ - if (dev_priv->irq_use_mask) - I915_WRITE(I915REG_INT_MASK_R, I915_INTERRUPT_ENABLE_MASK); - else - I915_WRITE(I915REG_INT_ENABLE_R, 0); -} - /** * i915_get_pipe - return the the pipe associated with a given plane * @dev: DRM device @@ -507,9 +450,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) u32 pipea_stats = 0, pipeb_stats = 0; int vblank = 0; - DRM_SPINLOCK(&dev_priv->user_irq_lock); if (dev->pdev->msi_enabled) - i915_disable_irqs(dev_priv); + I915_WRITE(I915REG_INT_MASK_R, ~0); iir = I915_READ(I915REG_INT_IDENTITY_R); #if 0 DRM_DEBUG("flag=%08x\n", iir); @@ -522,10 +464,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_READ(I915REG_INT_ENABLE_R), I915_READ(I915REG_PIPEASTAT), I915_READ(I915REG_PIPEBSTAT)); - if (dev->pdev->msi_enabled) - i915_enable_irqs(dev_priv); - - DRM_SPINUNLOCK(&dev_priv->user_irq_lock); + if (dev->pdev->msi_enabled) { + I915_WRITE(I915REG_INT_MASK_R, + dev_priv->irq_mask_reg); + (void) I915_READ(I915REG_INT_MASK_R); + } return IRQ_NONE; } @@ -543,12 +486,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) } I915_WRITE(I915REG_INT_IDENTITY_R, iir); - (void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted writes */ - if (dev->pdev->msi_enabled) - i915_enable_irqs(dev_priv); - - DRM_SPINUNLOCK(&dev_priv->user_irq_lock); + I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); + (void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted writes */ if (dev_priv->sarea_priv) dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); @@ -601,8 +541,14 @@ int i915_emit_irq(struct drm_device *dev) void i915_user_irq_on(drm_i915_private_t *dev_priv) { DRM_SPINLOCK(&dev_priv->user_irq_lock); - if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)) - i915_enable_irq(dev_priv, I915_USER_INTERRUPT); + if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ + if ((dev_priv->irq_mask_reg & I915_USER_INTERRUPT) != 0) { + dev_priv->irq_mask_reg &= ~I915_USER_INTERRUPT; + I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); + I915_WRITE(I915REG_INT_IDENTITY_R, I915_USER_INTERRUPT); + (void) I915_READ (I915REG_INT_MASK_R); + } + } DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } @@ -611,8 +557,13 @@ void i915_user_irq_off(drm_i915_private_t *dev_priv) { DRM_SPINLOCK(&dev_priv->user_irq_lock); BUG_ON(dev_priv->irq_enabled && dev_priv->user_irq_refcount <= 0); - if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) - i915_disable_irq(dev_priv, I915_USER_INTERRUPT); + if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { + if ((dev_priv->irq_mask_reg & I915_USER_INTERRUPT) == 0) { + dev_priv->irq_mask_reg |= I915_USER_INTERRUPT; + I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); + (void) I915_READ(I915REG_INT_MASK_R); + } + } DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } @@ -737,7 +688,9 @@ int i915_enable_vblank(struct drm_device *dev, int plane) I915_WRITE(pipestat_reg, pipestat); } DRM_SPINLOCK(&dev_priv->user_irq_lock); - i915_enable_irq(dev_priv, mask_reg); + dev_priv->irq_mask_reg &= ~mask_reg; + I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); + I915_READ(I915REG_INT_MASK_R); DRM_SPINUNLOCK(&dev_priv->user_irq_lock); return 0; @@ -767,7 +720,10 @@ void i915_disable_vblank(struct drm_device *dev, int plane) } DRM_SPINLOCK(&dev_priv->user_irq_lock); - i915_disable_irq(dev_priv, mask_reg); + dev_priv->irq_mask_reg |= mask_reg; + I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); + (void) I915_READ (I915REG_INT_MASK_R); + DRM_SPINUNLOCK(&dev_priv->user_irq_lock); if (pipestat_reg) { pipestat = I915_READ (pipestat_reg); @@ -781,24 +737,15 @@ void i915_disable_vblank(struct drm_device *dev, int plane) I915_WRITE(pipestat_reg, pipestat); (void) I915_READ(pipestat_reg); } - DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } static void i915_enable_interrupt (struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - dev_priv->irq_use_mask = 1; - if (dev_priv->irq_use_mask) { - dev_priv->irq_mask_reg = I915_INTERRUPT_ENABLE_MASK; - dev_priv->irq_enable_reg = I915_INTERRUPT_ENABLE_MASK; - } else { - dev_priv->irq_mask_reg = 0; - dev_priv->irq_enable_reg = 0; - } - I915_WRITE(I915REG_INT_IDENTITY_R, I915_READ(I915REG_INT_IDENTITY_R)); + dev_priv->irq_mask_reg = ~0; I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(I915REG_INT_ENABLE_R, I915_INTERRUPT_ENABLE_MASK); (void) I915_READ (I915REG_INT_ENABLE_R); dev_priv->irq_enabled = 1; } @@ -808,9 +755,9 @@ static void i915_disable_interrupt (struct drm_device *dev) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; I915_WRITE(I915REG_HWSTAM, 0xffffffff); - I915_WRITE(I915REG_INT_MASK_R, I915_INTERRUPT_ENABLE_MASK); + I915_WRITE(I915REG_INT_MASK_R, 0xffffffff); I915_WRITE(I915REG_INT_ENABLE_R, 0); - I915_WRITE(I915REG_INT_IDENTITY_R, I915_READ(I915REG_INT_IDENTITY_R)); + I915_WRITE(I915REG_INT_IDENTITY_R, 0xffffffff); (void) I915_READ (I915REG_INT_IDENTITY_R); dev_priv->irq_enabled = 0; } @@ -850,10 +797,7 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, return -EINVAL; } - if (dev_priv->irq_use_mask) - flag = ~dev_priv->irq_mask_reg; - else - flag = dev_priv->irq_enable_reg; + flag = I915_READ(I915REG_INT_ENABLE_R); pipe->pipe = 0; if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) pipe->pipe |= DRM_I915_VBLANK_PIPE_A; |