aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2007-09-27 21:46:28 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-09-27 22:47:28 -0400
commite4a7b1d1d90d202a030688ab5b177c3c0f15ee3e (patch)
treec8e8c64a69fc38daa32d04580195c703f9e5dc41 /drivers/char
parentff0ce6845bc18292e80ea40d11c3d3a539a3fc5e (diff)
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. [ Without this patch, my 965GM drops vblank interrupts - Jesse ] Signed-off-by: Dave Airlie <airlied@linux.ie> Acked-by: Jesse Barnes <jesse.barnes@intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/drm/i915_drv.h6
-rw-r--r--drivers/char/drm/i915_irq.c12
2 files changed, 18 insertions, 0 deletions
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 737088bd0780..28b98733beb8 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);
210#define I915REG_INT_MASK_R 0x020a8 210#define I915REG_INT_MASK_R 0x020a8
211#define I915REG_INT_ENABLE_R 0x020a0 211#define I915REG_INT_ENABLE_R 0x020a0
212 212
213#define I915REG_PIPEASTAT 0x70024
214#define I915REG_PIPEBSTAT 0x71024
215
216#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
217#define I915_VBLANK_CLEAR (1UL<<1)
218
213#define SRX_INDEX 0x3c4 219#define SRX_INDEX 0x3c4
214#define SRX_DATA 0x3c5 220#define SRX_DATA 0x3c5
215#define SR01 1 221#define SR01 1
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index 4b4b2ce89863..bb8e9e9c8201 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)
214 struct drm_device *dev = (struct drm_device *) arg; 214 struct drm_device *dev = (struct drm_device *) arg;
215 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 215 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
216 u16 temp; 216 u16 temp;
217 u32 pipea_stats, pipeb_stats;
218
219 pipea_stats = I915_READ(I915REG_PIPEASTAT);
220 pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
217 221
218 temp = I915_READ16(I915REG_INT_IDENTITY_R); 222 temp = I915_READ16(I915REG_INT_IDENTITY_R);
219 223
@@ -225,6 +229,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
225 return IRQ_NONE; 229 return IRQ_NONE;
226 230
227 I915_WRITE16(I915REG_INT_IDENTITY_R, temp); 231 I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
232 (void) I915_READ16(I915REG_INT_IDENTITY_R);
233 DRM_READMEMORYBARRIER();
228 234
229 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 235 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
230 236
@@ -252,6 +258,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
252 258
253 if (dev_priv->swaps_pending > 0) 259 if (dev_priv->swaps_pending > 0)
254 drm_locked_tasklet(dev, i915_vblank_tasklet); 260 drm_locked_tasklet(dev, i915_vblank_tasklet);
261 I915_WRITE(I915REG_PIPEASTAT,
262 pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
263 I915_VBLANK_CLEAR);
264 I915_WRITE(I915REG_PIPEBSTAT,
265 pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
266 I915_VBLANK_CLEAR);
255 } 267 }
256 268
257 return IRQ_HANDLED; 269 return IRQ_HANDLED;