summaryrefslogtreecommitdiff
path: root/shared-core/i915_irq.c
diff options
context:
space:
mode:
authorJesse Barnes <jesse.barnes@intel.com>2007-06-22 11:06:51 -0700
committerJesse Barnes <jesse.barnes@intel.com>2007-06-22 11:06:51 -0700
commit97dcd7fd25c18d5148619254229f8d94efb55b44 (patch)
treef7e1c4e47b45241027b5ceaeb726162fd82e2b56 /shared-core/i915_irq.c
parent2d24455ed8b12df6d06d135cb70f02473d11f4b0 (diff)
more vblank rework
- use a timer for disabling vblank events to avoid enable/disable calls too often - make i915 work with pre-965 chips again (would like to structure this better, but this hack works on my test system)
Diffstat (limited to 'shared-core/i915_irq.c')
-rw-r--r--shared-core/i915_irq.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index 713ec654..c0c1bf9e 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -285,6 +285,9 @@ u32 i915_get_vblank_counter(drm_device_t *dev, int crtc)
unsigned long low_frame = crtc ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
u32 high1, high2, low, count;
+ if (!IS_I965G(dev))
+ return 0;
+
/*
* High & low register fields aren't synchronized, so make sure
* we get a low value that's stable across two reads of the high
@@ -315,7 +318,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
temp = I915_READ16(I915REG_INT_IDENTITY_R);
- temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG);
#if 0
DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
@@ -324,7 +326,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
return IRQ_NONE;
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
- (void) I915_READ16(I915REG_INT_IDENTITY_R);
+ (void) I915_READ16(I915REG_INT_IDENTITY_R); /* Flush posted write */
+
+ temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | VSYNC_PIPEA_FLAG |
+ VSYNC_PIPEB_FLAG);
dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
@@ -335,6 +340,13 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
#endif
}
+ if (!IS_I965G(dev)) {
+ if (temp & VSYNC_PIPEA_FLAG)
+ atomic_inc(&dev->_vblank_count[0]);
+ if (temp & VSYNC_PIPEB_FLAG)
+ atomic_inc(&dev->_vblank_count[1]);
+ }
+
/*
* Use drm_update_vblank_counter here to deal with potential lost
* interrupts
@@ -482,6 +494,9 @@ int i915_enable_vblank(drm_device_t *dev, int crtc)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ if (!IS_I965G(dev))
+ return 0;
+
switch (crtc) {
case 0:
dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG;
@@ -504,6 +519,9 @@ void i915_disable_vblank(drm_device_t *dev, int crtc)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ if (!IS_I965G(dev))
+ return;
+
switch (crtc) {
case 0:
dev_priv->irq_enable_reg &= ~VSYNC_PIPEA_FLAG;
@@ -763,6 +781,11 @@ int i915_driver_irq_postinstall(drm_device_t * dev)
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+ if (!IS_I965G(dev)) {
+ dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG;
+ I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+ }
+
i915_enable_interrupt(dev);
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);