diff options
author | =?utf-8?q?Michel_D=C3=A4nzer?= <michel@tungstengraphics.com> | 2006-10-24 22:28:51 +1000 |
---|---|---|
committer | airlied <airlied@linux.ie> | 2006-12-07 15:53:28 +1100 |
commit | 68815bad7239989d92f315c10d9ef65a11945a75 (patch) | |
tree | 148ae38036feb708147022a8ecc57daa1b61d9c6 /drivers/char/drm | |
parent | 776c9443e28dddbde9b513db6cb8221c45b3a269 (diff) | |
download | blackbird-op-linux-68815bad7239989d92f315c10d9ef65a11945a75.tar.gz blackbird-op-linux-68815bad7239989d92f315c10d9ef65a11945a75.zip |
drm: add support for secondary vertical blank interrupt to i915
When the vertical blank interrupt is enabled for both pipes, pipe A is
considered primary and pipe B secondary. When it's only enabled for one pipe,
it's always considered primary for backwards compatibility.
Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm')
-rw-r--r-- | drivers/char/drm/i915_drv.c | 4 | ||||
-rw-r--r-- | drivers/char/drm/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/char/drm/i915_irq.c | 26 |
3 files changed, 27 insertions, 4 deletions
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 8e2e6095c4b3..85bcc276f804 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -44,12 +44,14 @@ static struct drm_driver driver = { */ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ - DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | + DRIVER_IRQ_VBL2, .load = i915_driver_load, .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, .device_is_agp = i915_driver_device_is_agp, .vblank_wait = i915_driver_vblank_wait, + .vblank_wait2 = i915_driver_vblank_wait2, .irq_preinstall = i915_driver_irq_preinstall, .irq_postinstall = i915_driver_irq_postinstall, .irq_uninstall = i915_driver_irq_uninstall, diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index fdc2bf192714..5f0c4fa04da2 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -117,6 +117,7 @@ extern int i915_irq_emit(DRM_IOCTL_ARGS); extern int i915_irq_wait(DRM_IOCTL_ARGS); extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence); +extern int i915_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence); extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); extern void i915_driver_irq_preinstall(drm_device_t * dev); extern void i915_driver_irq_postinstall(drm_device_t * dev); diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index 0d4a162aa385..33d40187696a 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c @@ -60,7 +60,16 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) DRM_WAKEUP(&dev_priv->irq_queue); if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { - atomic_inc(&dev->vbl_received); + if ((dev_priv->vblank_pipe & + (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) + == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) { + if (temp & VSYNC_PIPEA_FLAG) + atomic_inc(&dev->vbl_received); + if (temp & VSYNC_PIPEB_FLAG) + atomic_inc(&dev->vbl_received2); + } else + atomic_inc(&dev->vbl_received); + DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); } @@ -120,7 +129,8 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr) return ret; } -int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) +static int i915_driver_vblank_do_wait(drm_device_t *dev, unsigned int *sequence, + atomic_t *counter) { drm_i915_private_t *dev_priv = dev->dev_private; unsigned int cur_vblank; @@ -132,7 +142,7 @@ int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) } DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(&dev->vbl_received)) + (((cur_vblank = atomic_read(counter)) - *sequence) <= (1<<23))); *sequence = cur_vblank; @@ -141,6 +151,16 @@ int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) } +int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) +{ + return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); +} + +int i915_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence) +{ + return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2); +} + /* Needs the lock as it touches the ring. */ int i915_irq_emit(DRM_IOCTL_ARGS) |