aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/i915_irq.c
diff options
context:
space:
mode:
author=?utf-8?q?Michel_D=C3=A4nzer?= <michel@tungstengraphics.com>2006-10-24 08:28:51 -0400
committerairlied <airlied@linux.ie>2006-12-06 23:53:28 -0500
commit68815bad7239989d92f315c10d9ef65a11945a75 (patch)
tree148ae38036feb708147022a8ecc57daa1b61d9c6 /drivers/char/drm/i915_irq.c
parent776c9443e28dddbde9b513db6cb8221c45b3a269 (diff)
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/i915_irq.c')
-rw-r--r--drivers/char/drm/i915_irq.c26
1 files changed, 23 insertions, 3 deletions
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)
60 DRM_WAKEUP(&dev_priv->irq_queue); 60 DRM_WAKEUP(&dev_priv->irq_queue);
61 61
62 if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { 62 if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
63 atomic_inc(&dev->vbl_received); 63 if ((dev_priv->vblank_pipe &
64 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
65 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
66 if (temp & VSYNC_PIPEA_FLAG)
67 atomic_inc(&dev->vbl_received);
68 if (temp & VSYNC_PIPEB_FLAG)
69 atomic_inc(&dev->vbl_received2);
70 } else
71 atomic_inc(&dev->vbl_received);
72
64 DRM_WAKEUP(&dev->vbl_queue); 73 DRM_WAKEUP(&dev->vbl_queue);
65 drm_vbl_send_signals(dev); 74 drm_vbl_send_signals(dev);
66 } 75 }
@@ -120,7 +129,8 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr)
120 return ret; 129 return ret;
121} 130}
122 131
123int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) 132static int i915_driver_vblank_do_wait(drm_device_t *dev, unsigned int *sequence,
133 atomic_t *counter)
124{ 134{
125 drm_i915_private_t *dev_priv = dev->dev_private; 135 drm_i915_private_t *dev_priv = dev->dev_private;
126 unsigned int cur_vblank; 136 unsigned int cur_vblank;
@@ -132,7 +142,7 @@ int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
132 } 142 }
133 143
134 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, 144 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
135 (((cur_vblank = atomic_read(&dev->vbl_received)) 145 (((cur_vblank = atomic_read(counter))
136 - *sequence) <= (1<<23))); 146 - *sequence) <= (1<<23)));
137 147
138 *sequence = cur_vblank; 148 *sequence = cur_vblank;
@@ -141,6 +151,16 @@ int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
141} 151}
142 152
143 153
154int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
155{
156 return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
157}
158
159int i915_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence)
160{
161 return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
162}
163
144/* Needs the lock as it touches the ring. 164/* Needs the lock as it touches the ring.
145 */ 165 */
146int i915_irq_emit(DRM_IOCTL_ARGS) 166int i915_irq_emit(DRM_IOCTL_ARGS)