aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm
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
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')
-rw-r--r--drivers/char/drm/i915_drv.c4
-rw-r--r--drivers/char/drm/i915_drv.h1
-rw-r--r--drivers/char/drm/i915_irq.c26
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 = {
44 */ 44 */
45 .driver_features = 45 .driver_features =
46 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ 46 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
47 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, 47 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
48 DRIVER_IRQ_VBL2,
48 .load = i915_driver_load, 49 .load = i915_driver_load,
49 .lastclose = i915_driver_lastclose, 50 .lastclose = i915_driver_lastclose,
50 .preclose = i915_driver_preclose, 51 .preclose = i915_driver_preclose,
51 .device_is_agp = i915_driver_device_is_agp, 52 .device_is_agp = i915_driver_device_is_agp,
52 .vblank_wait = i915_driver_vblank_wait, 53 .vblank_wait = i915_driver_vblank_wait,
54 .vblank_wait2 = i915_driver_vblank_wait2,
53 .irq_preinstall = i915_driver_irq_preinstall, 55 .irq_preinstall = i915_driver_irq_preinstall,
54 .irq_postinstall = i915_driver_irq_postinstall, 56 .irq_postinstall = i915_driver_irq_postinstall,
55 .irq_uninstall = i915_driver_irq_uninstall, 57 .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);
117extern int i915_irq_wait(DRM_IOCTL_ARGS); 117extern int i915_irq_wait(DRM_IOCTL_ARGS);
118 118
119extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence); 119extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
120extern int i915_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence);
120extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); 121extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
121extern void i915_driver_irq_preinstall(drm_device_t * dev); 122extern void i915_driver_irq_preinstall(drm_device_t * dev);
122extern void i915_driver_irq_postinstall(drm_device_t * dev); 123extern 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)
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)