Messages in this thread Patch in this message | | | Date | Fri, 28 Sep 2007 03:05:31 +0100 (IST) | From | Dave Airlie <> | Subject | [PATCH] i915: make vbl interrupts work properly on i965g/gm |
| |
Hi Linus,
The attached patch is to fix a bug reported on 965gm chipsets (lots of new laptops), I think distros will all have to patch this in to fix it, so can we get it into the 2.6.23 final?
(Otherwise I'll wait until stable..)
Dave.From 14e53712e5e2ccc72dac1131de78e590e9a9d451 Mon Sep 17 00:00:00 2001 From: Dave Airlie <airlied@linux.ie> Date: Fri, 28 Sep 2007 11:46:28 +1000 Subject: [PATCH] i915: make vbl interrupts work properly on i965g/gm hw.
This code is ported from the DRM git tree and allows the vblank interrupts to function on the i965 hw. It also requires a change in Mesa's 965 driver to actually use them.
Signed-off-by: Dave Airlie <airlied@linux.ie> --- drivers/char/drm/i915_drv.h | 6 ++++++ drivers/char/drm/i915_irq.c | 12 ++++++++++++ 2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 737088b..28b9873 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -210,6 +210,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915REG_INT_MASK_R 0x020a8 #define I915REG_INT_ENABLE_R 0x020a0 +#define I915REG_PIPEASTAT 0x70024 +#define I915REG_PIPEBSTAT 0x71024 + +#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define I915_VBLANK_CLEAR (1UL<<1) + #define SRX_INDEX 0x3c4 #define SRX_DATA 0x3c5 #define SR01 1 diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index 4b4b2ce..bb8e9e9 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c @@ -214,6 +214,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u16 temp; + u32 pipea_stats, pipeb_stats; + + pipea_stats = I915_READ(I915REG_PIPEASTAT); + pipeb_stats = I915_READ(I915REG_PIPEBSTAT); temp = I915_READ16(I915REG_INT_IDENTITY_R); @@ -225,6 +229,8 @@ 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); + DRM_READMEMORYBARRIER(); dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); @@ -252,6 +258,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) if (dev_priv->swaps_pending > 0) drm_locked_tasklet(dev, i915_vblank_tasklet); + I915_WRITE(I915REG_PIPEASTAT, + pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); + I915_WRITE(I915REG_PIPEBSTAT, + pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); } return IRQ_HANDLED; -- 1.5.3.1
| |