Sync up the rest of the code that we use with what Intel is shipping
-Some irq/vblank related changes that hopefully will help. -A little more cleanup while I'm here. MFC after: 3 days
This commit is contained in:
parent
78db4b9606
commit
45592455be
@ -193,7 +193,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
|
|||||||
dev_priv->ring.map.flags = 0;
|
dev_priv->ring.map.flags = 0;
|
||||||
dev_priv->ring.map.mtrr = 0;
|
dev_priv->ring.map.mtrr = 0;
|
||||||
|
|
||||||
drm_core_ioremap(&dev_priv->ring.map, dev);
|
drm_core_ioremap_wc(&dev_priv->ring.map, dev);
|
||||||
|
|
||||||
if (dev_priv->ring.map.handle == NULL) {
|
if (dev_priv->ring.map.handle == NULL) {
|
||||||
i915_dma_cleanup(dev);
|
i915_dma_cleanup(dev);
|
||||||
@ -209,7 +209,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
|
|||||||
dev_priv->back_offset = init->back_offset;
|
dev_priv->back_offset = init->back_offset;
|
||||||
dev_priv->front_offset = init->front_offset;
|
dev_priv->front_offset = init->front_offset;
|
||||||
dev_priv->current_page = 0;
|
dev_priv->current_page = 0;
|
||||||
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
|
dev_priv->sarea_priv->pf_current_page = 0;
|
||||||
|
|
||||||
/* Allow hardware batchbuffers unless told otherwise.
|
/* Allow hardware batchbuffers unless told otherwise.
|
||||||
*/
|
*/
|
||||||
@ -721,7 +721,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data,
|
|||||||
|
|
||||||
DRM_DEBUG("%s\n", __func__);
|
DRM_DEBUG("%s\n", __func__);
|
||||||
|
|
||||||
LOCK_TEST_WITH_RETURN(dev, file_priv);
|
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
|
||||||
|
|
||||||
ret = i915_dispatch_flip(dev);
|
ret = i915_dispatch_flip(dev);
|
||||||
|
|
||||||
@ -758,7 +758,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
|
|||||||
value = 0;
|
value = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DRM_ERROR("Unknown parameter %d\n", param->param);
|
DRM_DEBUG("Unknown parameter %d\n", param->param);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,7 +791,7 @@ static int i915_setparam(struct drm_device *dev, void *data,
|
|||||||
dev_priv->allow_batchbuffer = param->value;
|
dev_priv->allow_batchbuffer = param->value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DRM_ERROR("unknown parameter %d\n", param->param);
|
DRM_DEBUG("unknown parameter %d\n", param->param);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,7 +822,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
|
|||||||
dev_priv->hws_map.flags = 0;
|
dev_priv->hws_map.flags = 0;
|
||||||
dev_priv->hws_map.mtrr = 0;
|
dev_priv->hws_map.mtrr = 0;
|
||||||
|
|
||||||
drm_core_ioremap(&dev_priv->hws_map, dev);
|
drm_core_ioremap_wc(&dev_priv->hws_map, dev);
|
||||||
if (dev_priv->hws_map.handle == NULL) {
|
if (dev_priv->hws_map.handle == NULL) {
|
||||||
i915_dma_cleanup(dev);
|
i915_dma_cleanup(dev);
|
||||||
dev_priv->status_gfx_addr = 0;
|
dev_priv->status_gfx_addr = 0;
|
||||||
@ -880,8 +880,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||||||
/* Init HWS */
|
/* Init HWS */
|
||||||
if (!I915_NEED_GFX_HWS(dev)) {
|
if (!I915_NEED_GFX_HWS(dev)) {
|
||||||
ret = i915_init_phys_hws(dev);
|
ret = i915_init_phys_hws(dev);
|
||||||
if (ret != 0)
|
if (ret != 0) {
|
||||||
|
drm_rmmap(dev, dev_priv->mmio_map);
|
||||||
|
drm_free(dev_priv, sizeof(struct drm_i915_private),
|
||||||
|
DRM_MEM_DRIVER);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
/* On the 945G/GM, the chipset reports the MSI capability on the
|
/* On the 945G/GM, the chipset reports the MSI capability on the
|
||||||
@ -901,6 +905,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||||||
intel_opregion_init(dev);
|
intel_opregion_init(dev);
|
||||||
#endif
|
#endif
|
||||||
DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
|
DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
|
||||||
|
dev_priv->user_irq_refcount = 0;
|
||||||
|
|
||||||
ret = drm_vblank_init(dev, I915_NUM_PIPE);
|
ret = drm_vblank_init(dev, I915_NUM_PIPE);
|
||||||
|
|
||||||
|
@ -43,21 +43,28 @@ __FBSDID("$FreeBSD$");
|
|||||||
* we leave them always unmasked in IMR and then control enabling them through
|
* we leave them always unmasked in IMR and then control enabling them through
|
||||||
* PIPESTAT alone.
|
* PIPESTAT alone.
|
||||||
*/
|
*/
|
||||||
#define I915_INTERRUPT_ENABLE_FIX (I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
|
#define I915_INTERRUPT_ENABLE_FIX (I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
|
||||||
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
|
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
|
||||||
|
|
||||||
/** Interrupts that we mask and unmask at runtime. */
|
/** Interrupts that we mask and unmask at runtime. */
|
||||||
#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
|
#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
|
||||||
|
|
||||||
/** These are all of the interrupts used by the driver */
|
/** These are all of the interrupts used by the driver */
|
||||||
#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
|
#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
|
||||||
I915_INTERRUPT_ENABLE_VAR)
|
I915_INTERRUPT_ENABLE_VAR)
|
||||||
|
|
||||||
|
#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\
|
||||||
|
PIPE_VBLANK_INTERRUPT_STATUS)
|
||||||
|
|
||||||
|
#define I915_PIPE_VBLANK_ENABLE (PIPE_START_VBLANK_INTERRUPT_ENABLE |\
|
||||||
|
PIPE_VBLANK_INTERRUPT_ENABLE)
|
||||||
|
|
||||||
|
#define DRM_I915_VBLANK_PIPE_ALL (DRM_I915_VBLANK_PIPE_A | \
|
||||||
|
DRM_I915_VBLANK_PIPE_B)
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
|
i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
|
||||||
{
|
{
|
||||||
DRM_DEBUG("irq_enable_reg = 0x%08x, mask = 0x%08x\n",
|
|
||||||
dev_priv->irq_mask_reg, mask);
|
|
||||||
mask &= I915_INTERRUPT_ENABLE_VAR;
|
mask &= I915_INTERRUPT_ENABLE_VAR;
|
||||||
if ((dev_priv->irq_mask_reg & mask) != 0) {
|
if ((dev_priv->irq_mask_reg & mask) != 0) {
|
||||||
dev_priv->irq_mask_reg &= ~mask;
|
dev_priv->irq_mask_reg &= ~mask;
|
||||||
@ -189,59 +196,84 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
u32 iir, new_iir;
|
u32 iir, new_iir;
|
||||||
u32 pipea_stats, pipeb_stats;
|
u32 pipea_stats, pipeb_stats;
|
||||||
|
u32 vblank_status;
|
||||||
|
u32 vblank_enable;
|
||||||
|
int irq_received;
|
||||||
|
|
||||||
atomic_inc(&dev_priv->irq_received);
|
atomic_inc(&dev_priv->irq_received);
|
||||||
|
|
||||||
for (iir = I915_READ(IIR) ; iir != 0 ; iir = new_iir) {
|
iir = I915_READ(IIR);
|
||||||
|
|
||||||
pipea_stats = pipeb_stats = 0;
|
if (IS_I965G(dev)) {
|
||||||
|
vblank_status = I915_START_VBLANK_INTERRUPT_STATUS;
|
||||||
|
vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE;
|
||||||
|
} else {
|
||||||
|
vblank_status = I915_VBLANK_INTERRUPT_STATUS;
|
||||||
|
vblank_enable = I915_VBLANK_INTERRUPT_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
irq_received = iir != 0;
|
||||||
|
|
||||||
|
/* Can't rely on pipestat interrupt bit in iir as it might
|
||||||
|
* have been cleared after the pipestat interrupt was received.
|
||||||
|
* It doesn't set the bit in iir again, but it still produces
|
||||||
|
* interrupts (for non-MSI).
|
||||||
|
*/
|
||||||
|
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||||
|
pipea_stats = I915_READ(PIPEASTAT);
|
||||||
|
pipeb_stats = I915_READ(PIPEBSTAT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the PIPE(A|B)STAT regs before the IIR
|
* Clear the PIPE(A|B)STAT regs before the IIR
|
||||||
*/
|
*/
|
||||||
if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
|
if (pipea_stats & 0x8000ffff) {
|
||||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
|
||||||
pipea_stats = I915_READ(PIPEASTAT);
|
|
||||||
I915_WRITE(PIPEASTAT, pipea_stats);
|
I915_WRITE(PIPEASTAT, pipea_stats);
|
||||||
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
irq_received = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
|
if (pipeb_stats & 0x8000ffff) {
|
||||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
|
||||||
pipeb_stats = I915_READ(PIPEBSTAT);
|
|
||||||
I915_WRITE(PIPEBSTAT, pipeb_stats);
|
I915_WRITE(PIPEBSTAT, pipeb_stats);
|
||||||
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
irq_received = 1;
|
||||||
}
|
}
|
||||||
|
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||||
|
|
||||||
|
if (!irq_received)
|
||||||
|
break;
|
||||||
|
|
||||||
I915_WRITE(IIR, iir);
|
I915_WRITE(IIR, iir);
|
||||||
new_iir = I915_READ(IIR);
|
new_iir = I915_READ(IIR); /* Flush posted writes */
|
||||||
|
|
||||||
DRM_DEBUG("iir = 0x%08x, pipestats a = 0x%08x, b = 0x%08x\n",
|
|
||||||
iir, pipea_stats, pipeb_stats);
|
|
||||||
|
|
||||||
if (dev_priv->sarea_priv)
|
if (dev_priv->sarea_priv)
|
||||||
dev_priv->sarea_priv->last_dispatch =
|
dev_priv->sarea_priv->last_dispatch =
|
||||||
READ_BREADCRUMB(dev_priv);
|
READ_BREADCRUMB(dev_priv);
|
||||||
|
|
||||||
if (iir & I915_USER_INTERRUPT) {
|
if (iir & I915_USER_INTERRUPT) {
|
||||||
#ifdef I915_HAVE_GEM
|
|
||||||
dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
|
|
||||||
#endif
|
|
||||||
DRM_WAKEUP(&dev_priv->irq_queue);
|
DRM_WAKEUP(&dev_priv->irq_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS |
|
if (pipea_stats & vblank_status)
|
||||||
PIPE_VBLANK_INTERRUPT_STATUS))
|
|
||||||
drm_handle_vblank(dev, 0);
|
drm_handle_vblank(dev, 0);
|
||||||
|
|
||||||
if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS |
|
if (pipeb_stats & vblank_status)
|
||||||
PIPE_VBLANK_INTERRUPT_STATUS))
|
|
||||||
drm_handle_vblank(dev, 1);
|
drm_handle_vblank(dev, 1);
|
||||||
#ifdef __linux__
|
|
||||||
if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
|
/* With MSI, interrupts are only generated when iir
|
||||||
(iir & I915_ASLE_INTERRUPT))
|
* transitions from zero to nonzero. If another bit got
|
||||||
opregion_asle_intr(dev);
|
* set while we were handling the existing iir bits, then
|
||||||
#endif
|
* we would never get another interrupt.
|
||||||
|
*
|
||||||
|
* This is fine on non-MSI as well, as if we hit this path
|
||||||
|
* we avoid exiting the interrupt handler only to generate
|
||||||
|
* another one.
|
||||||
|
*
|
||||||
|
* Note that for MSI this could cause a stray interrupt report
|
||||||
|
* if an interrupt landed in the time between writing IIR and
|
||||||
|
* the posting read. This should be rare enough to never
|
||||||
|
* trigger the 99% of 100,000 interrupts test for disabling
|
||||||
|
* stray interrupts.
|
||||||
|
*/
|
||||||
|
iir = new_iir;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,27 +305,25 @@ static int i915_emit_irq(struct drm_device * dev)
|
|||||||
void i915_user_irq_get(struct drm_device *dev)
|
void i915_user_irq_get(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
unsigned long irqflags;
|
|
||||||
|
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
DRM_SPINLOCK_IRQSAVE(&dev_priv->user_irq_lock, irqflags);
|
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||||
if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
|
if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
|
||||||
i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
|
i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
|
||||||
DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->user_irq_lock, irqflags);
|
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i915_user_irq_put(struct drm_device *dev)
|
void i915_user_irq_put(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
unsigned long irqflags;
|
|
||||||
|
|
||||||
DRM_SPINLOCK_IRQSAVE(&dev_priv->user_irq_lock, irqflags);
|
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||||
#ifdef __linux__
|
if (dev->irq_enabled) {
|
||||||
BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
|
KASSERT(dev_priv->user_irq_refcount > 0, ("invalid refcount"));
|
||||||
#endif
|
if (--dev_priv->user_irq_refcount == 0)
|
||||||
if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0))
|
i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
|
||||||
i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
|
}
|
||||||
DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->user_irq_lock, irqflags);
|
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int i915_wait_irq(struct drm_device * dev, int irq_nr)
|
static int i915_wait_irq(struct drm_device * dev, int irq_nr)
|
||||||
@ -320,15 +350,14 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
|
|||||||
READ_BREADCRUMB(dev_priv) >= irq_nr);
|
READ_BREADCRUMB(dev_priv) >= irq_nr);
|
||||||
i915_user_irq_put(dev);
|
i915_user_irq_put(dev);
|
||||||
|
|
||||||
|
if (ret == -ERESTART)
|
||||||
|
DRM_DEBUG("restarting syscall\n");
|
||||||
|
|
||||||
if (ret == -EBUSY) {
|
if (ret == -EBUSY) {
|
||||||
DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
|
DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
|
||||||
READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
|
READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_priv->sarea_priv)
|
|
||||||
dev_priv->sarea_priv->last_dispatch =
|
|
||||||
READ_BREADCRUMB(dev_priv);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,13 +370,13 @@ int i915_irq_emit(struct drm_device *dev, void *data,
|
|||||||
drm_i915_irq_emit_t *emit = data;
|
drm_i915_irq_emit_t *emit = data;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
|
|
||||||
|
|
||||||
if (!dev_priv) {
|
if (!dev_priv) {
|
||||||
DRM_ERROR("called with no initialization\n");
|
DRM_ERROR("called with no initialization\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
|
||||||
|
|
||||||
result = i915_emit_irq(dev);
|
result = i915_emit_irq(dev);
|
||||||
|
|
||||||
if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
|
if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
|
||||||
@ -380,21 +409,21 @@ int i915_irq_wait(struct drm_device *dev, void *data,
|
|||||||
int i915_enable_vblank(struct drm_device *dev, int pipe)
|
int i915_enable_vblank(struct drm_device *dev, int pipe)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
unsigned long irqflags;
|
int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
|
||||||
u32 pipestat;
|
u32 pipeconf;
|
||||||
|
|
||||||
/*
|
pipeconf = I915_READ(pipeconf_reg);
|
||||||
* Older chips didn't have the start vblank interrupt,
|
if (!(pipeconf & PIPEACONF_ENABLE))
|
||||||
* but
|
return -EINVAL;
|
||||||
*/
|
|
||||||
if (IS_I965G (dev))
|
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||||
pipestat = PIPE_START_VBLANK_INTERRUPT_ENABLE;
|
if (IS_I965G(dev))
|
||||||
|
i915_enable_pipestat(dev_priv, pipe,
|
||||||
|
PIPE_START_VBLANK_INTERRUPT_ENABLE);
|
||||||
else
|
else
|
||||||
pipestat = PIPE_VBLANK_INTERRUPT_ENABLE;
|
i915_enable_pipestat(dev_priv, pipe,
|
||||||
|
PIPE_VBLANK_INTERRUPT_ENABLE);
|
||||||
DRM_SPINLOCK_IRQSAVE(&dev_priv->user_irq_lock, irqflags);
|
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||||
i915_enable_pipestat(dev_priv, pipe, pipestat);
|
|
||||||
DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->user_irq_lock, irqflags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,12 +433,12 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
|
|||||||
void i915_disable_vblank(struct drm_device *dev, int pipe)
|
void i915_disable_vblank(struct drm_device *dev, int pipe)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
unsigned long irqflags;
|
|
||||||
|
|
||||||
DRM_SPINLOCK_IRQSAVE(&dev_priv->user_irq_lock, irqflags);
|
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||||
i915_disable_pipestat(dev_priv, pipe,
|
i915_disable_pipestat(dev_priv, pipe,
|
||||||
PIPE_START_VBLANK_INTERRUPT_ENABLE | PIPE_VBLANK_INTERRUPT_ENABLE);
|
PIPE_VBLANK_INTERRUPT_ENABLE |
|
||||||
DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->user_irq_lock, irqflags);
|
PIPE_START_VBLANK_INTERRUPT_ENABLE);
|
||||||
|
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the vblank monitor pipe
|
/* Set the vblank monitor pipe
|
||||||
@ -463,7 +492,6 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
|
|||||||
* Context switching to userland and back is plenty fast enough for
|
* Context switching to userland and back is plenty fast enough for
|
||||||
* meeting the requirements of vblank swapping.
|
* meeting the requirements of vblank swapping.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,6 +501,8 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
|
|||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
|
|
||||||
|
atomic_set_int(&dev_priv->irq_received, 0);
|
||||||
|
|
||||||
I915_WRITE(HWSTAM, 0xeffe);
|
I915_WRITE(HWSTAM, 0xeffe);
|
||||||
I915_WRITE(PIPEASTAT, 0);
|
I915_WRITE(PIPEASTAT, 0);
|
||||||
I915_WRITE(PIPEBSTAT, 0);
|
I915_WRITE(PIPEBSTAT, 0);
|
||||||
@ -505,13 +535,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
|
|||||||
I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
|
I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
|
||||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||||
(void) I915_READ(IER);
|
(void) I915_READ(IER);
|
||||||
#ifdef __linux__
|
|
||||||
opregion_enable_asle(dev);
|
|
||||||
#endif
|
|
||||||
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
|
|
||||||
|
|
||||||
i915_enable_vblank(dev, 0);
|
|
||||||
i915_enable_vblank(dev, 1);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user