irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { drm_device_t *dev = (drm_device_t *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u16 temp; temp = I915_READ16(I915REG_INT_IDENTITY_R); temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); if (temp == 0) return IRQ_NONE; I915_WRITE16(I915REG_INT_IDENTITY_R, temp); dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); if (temp & USER_INT_FLAG) DRM_WAKEUP(&dev_priv->irq_queue); if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); } return IRQ_HANDLED; }
static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) { struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; uint32_t pipestat; int wake = 0; int vsync_a = 0; int vsync_b = 0; static int pipe_a_on = 0; static int pipe_b_on = 0; int trigger_2d_blit = 0; pipestat = PSB_RVDC32(PSB_PIPEASTAT); if (pipestat & (1<<31)) { printk("buffer underrun 0x%x\n",underrun++); PSB_WVDC32(1<<31 | 1<<15, PSB_PIPEASTAT); } if ((!drm_psb_disable_vsync) && (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)) { atomic_inc(&dev->vbl_received); wake = 1; PSB_WVDC32(_PSB_VBLANK_INTERRUPT_ENABLE | _PSB_VBLANK_CLEAR, PSB_PIPEASTAT); } if ((!drm_psb_disable_vsync) && (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)) { atomic_inc(&dev->vbl_received2); wake = 1; PSB_WVDC32(_PSB_VBLANK_INTERRUPT_ENABLE | _PSB_VBLANK_CLEAR, PSB_PIPEBSTAT); } if (vdc_stat & _PSB_HOTPLUG_INTERRUPT_FLAG) { // Clear 2nd status register spin_lock(&dev_priv->irqmask_lock); uint32_t hotplugstat = PSB_RVDC32(PORT_HOTPLUG_STATUS_REG); PSB_WVDC32(hotplugstat, PORT_HOTPLUG_STATUS_REG); spin_unlock(&dev_priv->irqmask_lock); hotplug_env = '1'; wake_up_interruptible(&hotplug_queue); } PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); (void)PSB_RVDC32(PSB_INT_IDENTITY_R); DRM_READMEMORYBARRIER(); if (wake) { DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); } }
irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; u32 stat; /* Only consider the bits we're interested in - others could be used * outside the DRM */ stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT)); if (!stat) return IRQ_NONE; stat &= dev_priv->irq_enable_reg; /* SW interrupt */ if (stat & RADEON_SW_INT_TEST) { DRM_WAKEUP(&dev_priv->swi_queue); } /* VBLANK interrupt */ if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { int vblank_crtc = dev_priv->vblank_crtc; if ((vblank_crtc & (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { if (stat & RADEON_CRTC_VBLANK_STAT) atomic_inc(&dev->vbl_received); if (stat & RADEON_CRTC2_VBLANK_STAT) atomic_inc(&dev->vbl_received2); } else if (((stat & RADEON_CRTC_VBLANK_STAT) && (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || ((stat & RADEON_CRTC2_VBLANK_STAT) && (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); } return IRQ_HANDLED; }
irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; int status; status = R128_READ(R128_GEN_INT_STATUS); /* VBLANK interrupt */ if (status & R128_CRTC_VBLANK_INT) { R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); return IRQ_HANDLED; } return IRQ_NONE; }
irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) { drm_device_t *dev = (drm_device_t *) arg; drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; int status; int handled = 0; status = MGA_READ(MGA_STATUS); /* VBLANK interrupt */ if (status & MGA_VLINEPEN) { MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); handled = 1; } /* SOFTRAP interrupt */ if (status & MGA_SOFTRAPEN) { const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); const u32 prim_end = MGA_READ(MGA_PRIMEND); MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); /* In addition to clearing the interrupt-pending bit, we * have to write to MGA_PRIMEND to re-start the DMA operation. */ if ( (prim_start & ~0x03) != (prim_end & ~0x03) ) { MGA_WRITE(MGA_PRIMEND, prim_end); } atomic_inc(&dev_priv->last_fence_retired); DRM_WAKEUP(&dev_priv->fence_queue); handled = 1; } if ( handled ) { return IRQ_HANDLED; } return IRQ_NONE; }