[i915] leave interrupts masked off when not in use.
The interrupt enable register cannot be used to temporarily disable interrupts, instead use the interrupt mask register. Note that this change means that a pile of buffers will be left stuck on the chip as the final interrupts will not be recognized to come and drain things.main
parent
7cf3fd29fe
commit
d434b64f6a
|
@ -311,11 +311,13 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)
|
|||
|
||||
BUG_ON(seqno == 0);
|
||||
|
||||
i915_user_irq_on(dev_priv);
|
||||
ret = wait_event_interruptible(dev_priv->irq_queue,
|
||||
i915_seqno_passed(i915_get_gem_seqno(dev),
|
||||
seqno));
|
||||
i915_user_irq_off(dev_priv);
|
||||
if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
|
||||
i915_user_irq_on(dev_priv);
|
||||
ret = wait_event_interruptible(dev_priv->irq_queue,
|
||||
i915_seqno_passed(i915_get_gem_seqno(dev),
|
||||
seqno));
|
||||
i915_user_irq_off(dev_priv);
|
||||
}
|
||||
|
||||
/* Directly dispatch request retiring. While we have the work queue
|
||||
* to handle this, the waiter on a request often wants an associated
|
||||
|
@ -1538,6 +1540,7 @@ int
|
|||
i915_gem_flush_pwrite(struct drm_gem_object *obj,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
#if 0
|
||||
struct drm_device *dev = obj->dev;
|
||||
struct drm_i915_gem_object *obj_priv = obj->driver_private;
|
||||
|
||||
|
@ -1555,6 +1558,7 @@ i915_gem_flush_pwrite(struct drm_gem_object *obj,
|
|||
drm_agp_chipset_flush(dev);
|
||||
obj->write_domain = 0;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ typedef struct drm_i915_private {
|
|||
DRM_SPINTYPE user_irq_lock;
|
||||
int user_irq_refcount;
|
||||
int fence_irq_on;
|
||||
uint32_t irq_enable_reg;
|
||||
uint32_t irq_mask_reg;
|
||||
int irq_enabled;
|
||||
|
||||
#ifdef I915_HAVE_FENCE
|
||||
|
|
|
@ -508,7 +508,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
if (dev_priv->sarea_priv)
|
||||
dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
|
||||
|
||||
I915_WRITE(I915REG_INT_IDENTITY_R, iir);
|
||||
I915_WRITE(I915REG_INT_IDENTITY_R, iir | I915_USER_INTERRUPT);
|
||||
(void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted write */
|
||||
|
||||
if (iir & I915_USER_INTERRUPT) {
|
||||
|
@ -550,8 +550,9 @@ 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)){
|
||||
dev_priv->irq_enable_reg |= I915_USER_INTERRUPT;
|
||||
I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
|
||||
dev_priv->irq_mask_reg &= ~I915_USER_INTERRUPT;
|
||||
I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg);
|
||||
(void) I915_READ (I915REG_INT_ENABLE_R);
|
||||
}
|
||||
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||
|
||||
|
@ -560,9 +561,11 @@ void i915_user_irq_on(drm_i915_private_t *dev_priv)
|
|||
void i915_user_irq_off(drm_i915_private_t *dev_priv)
|
||||
{
|
||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||
BUG_ON(dev_priv->user_irq_refcount <= 0);
|
||||
if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
|
||||
// dev_priv->irq_enable_reg &= ~USER_INT_FLAG;
|
||||
// I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
|
||||
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);
|
||||
}
|
||||
|
@ -642,16 +645,17 @@ int i915_enable_vblank(struct drm_device *dev, int plane)
|
|||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
int pipe = i915_get_pipe(dev, plane);
|
||||
u32 pipestat_reg = 0;
|
||||
u32 mask_reg = 0;
|
||||
u32 pipestat;
|
||||
|
||||
switch (pipe) {
|
||||
case 0:
|
||||
pipestat_reg = I915REG_PIPEASTAT;
|
||||
dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
|
||||
mask_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
|
||||
break;
|
||||
case 1:
|
||||
pipestat_reg = I915REG_PIPEBSTAT;
|
||||
dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
|
||||
mask_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
|
||||
|
@ -677,7 +681,11 @@ int i915_enable_vblank(struct drm_device *dev, int plane)
|
|||
I915_VBLANK_INTERRUPT_STATUS);
|
||||
I915_WRITE(pipestat_reg, pipestat);
|
||||
}
|
||||
I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
|
||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||
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;
|
||||
}
|
||||
|
@ -687,16 +695,17 @@ void i915_disable_vblank(struct drm_device *dev, int plane)
|
|||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
int pipe = i915_get_pipe(dev, plane);
|
||||
u32 pipestat_reg = 0;
|
||||
u32 mask_reg = 0;
|
||||
u32 pipestat;
|
||||
|
||||
switch (pipe) {
|
||||
case 0:
|
||||
pipestat_reg = I915REG_PIPEASTAT;
|
||||
dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
|
||||
mask_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
|
||||
break;
|
||||
case 1:
|
||||
pipestat_reg = I915REG_PIPEBSTAT;
|
||||
dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
|
||||
mask_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
|
||||
|
@ -704,7 +713,11 @@ void i915_disable_vblank(struct drm_device *dev, int plane)
|
|||
break;
|
||||
}
|
||||
|
||||
I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
|
||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||
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);
|
||||
|
@ -716,6 +729,7 @@ void i915_disable_vblank(struct drm_device *dev, int plane)
|
|||
pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS |
|
||||
I915_VBLANK_INTERRUPT_STATUS);
|
||||
I915_WRITE(pipestat_reg, pipestat);
|
||||
(void) I915_READ(pipestat_reg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -723,12 +737,27 @@ 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_enable_reg |= I915_USER_INTERRUPT;
|
||||
|
||||
I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
|
||||
dev_priv->irq_mask_reg = (I915_USER_INTERRUPT |
|
||||
I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
|
||||
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
|
||||
I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg);
|
||||
I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_mask_reg);
|
||||
(void) I915_READ (I915REG_INT_ENABLE_R);
|
||||
dev_priv->irq_enabled = 1;
|
||||
}
|
||||
|
||||
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, 0xffffffff);
|
||||
I915_WRITE(I915REG_INT_ENABLE_R, 0);
|
||||
I915_WRITE(I915REG_INT_IDENTITY_R, 0xffffffff);
|
||||
(void) I915_READ (I915REG_INT_IDENTITY_R);
|
||||
dev_priv->irq_enabled = 0;
|
||||
}
|
||||
|
||||
/* Set the vblank monitor pipe
|
||||
*/
|
||||
int i915_vblank_pipe_set(struct drm_device *dev, void *data,
|
||||
|
@ -934,9 +963,11 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
|
|||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
|
||||
I915_WRITE16(I915REG_HWSTAM, 0xeffe);
|
||||
I915_WRITE16(I915REG_INT_MASK_R, 0x0);
|
||||
I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
|
||||
I915_WRITE(I915REG_HWSTAM, 0xffff);
|
||||
I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
|
||||
I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
|
||||
I915_WRITE(I915REG_INT_IDENTITY_R, 0xffffffff);
|
||||
(void) I915_READ(I915REG_INT_IDENTITY_R);
|
||||
}
|
||||
|
||||
int i915_driver_irq_postinstall(struct drm_device * dev)
|
||||
|
@ -950,7 +981,7 @@ int i915_driver_irq_postinstall(struct drm_device * dev)
|
|||
|
||||
DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
|
||||
dev_priv->user_irq_refcount = 0;
|
||||
dev_priv->irq_enable_reg = 0;
|
||||
dev_priv->irq_mask_reg = 0;
|
||||
|
||||
ret = drm_vblank_init(dev, num_pipes);
|
||||
if (ret)
|
||||
|
@ -977,15 +1008,10 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
|
|||
if (!dev_priv)
|
||||
return;
|
||||
|
||||
dev_priv->irq_enabled = 0;
|
||||
I915_WRITE(I915REG_HWSTAM, 0xffffffff);
|
||||
I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
|
||||
I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
|
||||
i915_disable_interrupt (dev);
|
||||
|
||||
temp = I915_READ(I915REG_PIPEASTAT);
|
||||
I915_WRITE(I915REG_PIPEASTAT, temp);
|
||||
temp = I915_READ(I915REG_PIPEBSTAT);
|
||||
I915_WRITE(I915REG_PIPEBSTAT, temp);
|
||||
temp = I915_READ(I915REG_INT_IDENTITY_R);
|
||||
I915_WRITE(I915REG_INT_IDENTITY_R, temp);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue