aboutsummaryrefslogtreecommitdiff
path: root/shared-core/i915_irq.c
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@jbarnes-t61.(none)>2008-06-18 15:25:54 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-06-18 15:25:54 -0700
commit86accbcb344ff25fbb47a788bb0f7464b5cd797f (patch)
treed023b852e7dab469bcc1d2b7f37493709e657fe5 /shared-core/i915_irq.c
parentc843d47b906e57fb3002af4a609d3cb95c5e195d (diff)
parente7424e4580159b0ac3e232674dff5c862e851dff (diff)
Merge commit 'origin/drm-gem' into modesetting-gem
Lots of conflicts, seems to load ok, but I'm sure some bugs snuck in. Conflicts: linux-core/drmP.h linux-core/drm_lock.c linux-core/i915_gem.c shared-core/drm.h shared-core/i915_dma.c shared-core/i915_drv.h shared-core/i915_irq.c
Diffstat (limited to 'shared-core/i915_irq.c')
-rw-r--r--shared-core/i915_irq.c70
1 files changed, 35 insertions, 35 deletions
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index bd11d37a..0dea6e56 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -35,6 +35,13 @@
#define MAX_NOPID ((u32)~0)
+/*
+ * These are the interrupts used by the driver
+ */
+#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
+
/**
* i915_get_pipe - return the the pipe associated with a given plane
* @dev: DRM device
@@ -493,28 +500,13 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat)
return 0;
}
-void
-i915_user_interrupt_handler(struct work_struct *work)
-{
- struct drm_i915_private *dev_priv;
- struct drm_device *dev;
-
- dev_priv = container_of(work, struct drm_i915_private,
- user_interrupt_task);
- dev = dev_priv->dev;
-
- mutex_lock(&dev->struct_mutex);
- i915_gem_retire_requests(dev);
- mutex_unlock(&dev->struct_mutex);
-}
-
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
struct drm_i915_master_private *master_priv;
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
u32 iir;
- u32 pipea_stats = 0, pipeb_stats, tvdac;
+ u32 pipea_stats = 0, pipeb_stats = 0, tvdac;
int hotplug = 0;
int vblank = 0;
@@ -524,22 +516,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
else
iir = I915_READ16(IIR);
- iir &= (dev_priv->irq_mask_reg | I915_USER_INTERRUPT);
+ if (dev->pdev->msi_enabled)
+ I915_WRITE(IER, 0);
-#if 0
- DRM_DEBUG("flag=%08x\n", iir);
-#endif
- if (iir == 0) {
-#if 0
- DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n",
- iir,
- I915_READ(IMR),
- I915_READ(IER),
- I915_READ(PIPEASTAT),
- I915_READ(PIPEBSTAT));
-#endif
+ if (!iir)
return IRQ_NONE;
- }
/*
* Clear the PIPE(A|B)STAT regs before the IIR otherwise
@@ -598,10 +579,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
DRM_WAKEUP(&dev_priv->irq_queue);
#ifdef I915_HAVE_FENCE
i915_fence_handler(dev);
- schedule_work(&dev_priv->user_interrupt_task);
#endif
}
+ if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
+ I915_VBLANK_INTERRUPT_STATUS)) {
+ vblank = 1;
+ drm_handle_vblank(dev, i915_get_plane(dev, 0));
+ }
+ if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
+ I915_VBLANK_INTERRUPT_STATUS)) {
+ vblank = 1;
+ drm_handle_vblank(dev, i915_get_plane(dev, 1));
+ }
if (vblank) {
if (dev_priv->swaps_pending > 0)
drm_locked_tasklet(dev, i915_vblank_tasklet);
@@ -626,6 +616,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
i915_run_hotplug_tasklet(dev, temp2);
}
+ if (dev->pdev->msi_enabled)
+ I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
+
return IRQ_HANDLED;
}
@@ -697,8 +690,17 @@ int i915_wait_irq(struct drm_device * dev, int irq_nr)
DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
READ_BREADCRUMB(dev_priv));
- if (READ_BREADCRUMB(dev_priv) >= irq_nr)
+ master_priv = dev->primary->master->driver_priv;
+
+ if (!master_priv) {
+ DRM_ERROR("no master priv?\n");
+ return -EINVAL;
+ }
+
+ if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
+ master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
return 0;
+ }
i915_user_irq_on(dev);
DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
@@ -710,10 +712,8 @@ int i915_wait_irq(struct drm_device * dev, int irq_nr)
READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
}
- if (dev->primary->master) {
- master_priv = dev->primary->master->driver_priv;
+ if (READ_BREADCRUMB(dev_priv) >= irq_nr)
master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
- }
return ret;
}