diff options
Diffstat (limited to 'shared-core/i915_irq.c')
-rw-r--r-- | shared-core/i915_irq.c | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index fe617557..418e0ae9 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -480,16 +480,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) } #ifdef __linux__ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) if (pipeb_stats & I915_LEGACY_BLC_EVENT_ENABLE) opregion_asle_intr(dev); #endif +#endif I915_WRITE(PIPEBSTAT, pipeb_stats); } #ifdef __linux__ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) if (iir & I915_ASLE_INTERRUPT) opregion_asle_intr(dev); #endif +#endif if (dev_priv->sarea_priv) dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); @@ -720,7 +724,7 @@ void i915_disable_vblank(struct drm_device *dev, int plane) } } -void i915_enable_interrupt (struct drm_device *dev) +static void i915_enable_interrupt (struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -730,8 +734,10 @@ void i915_enable_interrupt (struct drm_device *dev) (void) I915_READ (IER); #ifdef __linux__ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) opregion_enable_asle(dev); #endif +#endif dev_priv->irq_enabled = 1; } @@ -930,15 +936,63 @@ int i915_vblank_swap(struct drm_device *dev, void *data, */ void i915_driver_irq_preinstall(struct drm_device * dev) { - return; + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + + I915_WRITE16(HWSTAM, 0xeffe); + I915_WRITE16(IMR, 0x0); + I915_WRITE16(IER, 0x0); } int i915_driver_irq_postinstall(struct drm_device * dev) { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + int ret, num_pipes = 2; + + DRM_SPININIT(&dev_priv->swaps_lock, "swap"); + INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); + dev_priv->swaps_pending = 0; + + DRM_SPININIT(&dev_priv->user_irq_lock, "userirq"); + dev_priv->user_irq_refcount = 0; + dev_priv->irq_mask_reg = ~0; + + ret = drm_vblank_init(dev, num_pipes); + if (ret) + return ret; + + dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ + + i915_enable_interrupt(dev); + DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); + + /* + * Initialize the hardware status page IRQ location. + */ + + I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); return 0; } void i915_driver_irq_uninstall(struct drm_device * dev) { - return; + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 temp; + + if (!dev_priv) + return; + + dev_priv->vblank_pipe = 0; + + dev_priv->irq_enabled = 0; + I915_WRITE(HWSTAM, 0xffffffff); + I915_WRITE(IMR, 0xffffffff); + I915_WRITE(IER, 0x0); + + temp = I915_READ(PIPEASTAT); + I915_WRITE(PIPEASTAT, temp); + temp = I915_READ(PIPEBSTAT); + I915_WRITE(PIPEBSTAT, temp); + temp = I915_READ(IIR); + I915_WRITE(IIR, temp); } |