From 97dcd7fd25c18d5148619254229f8d94efb55b44 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 22 Jun 2007 11:06:51 -0700 Subject: 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) --- shared-core/i915_irq.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_irq.c') 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); -- cgit v1.2.3