i915: Only turn on user IRQs when they are needed.
parent
8c613a8363
commit
034fc31292
|
@ -58,13 +58,9 @@ static void i915_perform_flush(drm_device_t * dev)
|
|||
diff = sequence - fm->exe_flush_sequence;
|
||||
if (diff < driver->wrap_diff) {
|
||||
fm->pending_exe_flush = 0;
|
||||
/*
|
||||
* Turn off user IRQs
|
||||
*/
|
||||
i915_user_irq_off(dev_priv);
|
||||
} else {
|
||||
/*
|
||||
* Turn on user IRQs
|
||||
*/
|
||||
i915_user_irq_on(dev_priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,6 +103,10 @@ typedef struct drm_i915_private {
|
|||
struct mem_block *agp_heap;
|
||||
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
|
||||
int vblank_pipe;
|
||||
spinlock_t user_irq_lock;
|
||||
int user_irq_refcount;
|
||||
uint32_t irq_enable_reg;
|
||||
int irq_enabled;
|
||||
|
||||
#ifdef I915_HAVE_FENCE
|
||||
uint32_t flush_sequence;
|
||||
|
@ -139,6 +143,8 @@ extern void i915_driver_irq_uninstall(drm_device_t * dev);
|
|||
extern int i915_vblank_pipe_set(DRM_IOCTL_ARGS);
|
||||
extern int i915_vblank_pipe_get(DRM_IOCTL_ARGS);
|
||||
extern int i915_emit_irq(drm_device_t * dev);
|
||||
extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
|
||||
extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
|
||||
|
||||
/* i915_mem.c */
|
||||
extern int i915_mem_alloc(DRM_IOCTL_ARGS);
|
||||
|
|
|
@ -102,6 +102,29 @@ int i915_emit_irq(drm_device_t * dev)
|
|||
|
||||
}
|
||||
|
||||
void i915_user_irq_on(drm_i915_private_t *dev_priv)
|
||||
{
|
||||
|
||||
spin_lock(&dev_priv->user_irq_lock);
|
||||
if (dev_priv->irq_enabled && (++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);
|
||||
|
||||
}
|
||||
|
||||
void i915_user_irq_off(drm_i915_private_t *dev_priv)
|
||||
{
|
||||
spin_lock(&dev_priv->user_irq_lock);
|
||||
if (dev_priv->irq_enabled && (--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;
|
||||
|
@ -114,9 +137,11 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr)
|
|||
return 0;
|
||||
|
||||
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,
|
||||
READ_BREADCRUMB(dev_priv) >= irq_nr);
|
||||
i915_user_irq_off(dev_priv);
|
||||
|
||||
if (ret == DRM_ERR(EBUSY)) {
|
||||
DRM_ERROR("%s: EBUSY -- rec: %d emitted: %d\n",
|
||||
|
@ -211,7 +236,11 @@ static int i915_enable_interrupt (drm_device_t *dev)
|
|||
__FUNCTION__, dev_priv->vblank_pipe);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
|
||||
dev_priv->user_irq_lock = SPIN_LOCK_UNLOCKED;
|
||||
dev_priv->user_irq_refcount = 0;
|
||||
dev_priv->irq_enable_reg = flag;
|
||||
I915_WRITE16(I915REG_INT_ENABLE_R, flag);
|
||||
dev_priv->irq_enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -290,6 +319,7 @@ void i915_driver_irq_uninstall(drm_device_t * dev)
|
|||
if (!dev_priv)
|
||||
return;
|
||||
|
||||
dev_priv->irq_enabled = 0;
|
||||
I915_WRITE16(I915REG_HWSTAM, 0xffff);
|
||||
I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
|
||||
I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
|
||||
|
|
Loading…
Reference in New Issue