Commit 68815bad authored by =?utf-8?q?Michel_D=C3=A4nzer?='s avatar =?utf-8?q?Michel_D=C3=A4nzer?= Committed by airlied

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: default avatarDave Airlie <airlied@linux.ie>
parent 776c9443
...@@ -44,12 +44,14 @@ static struct drm_driver driver = { ...@@ -44,12 +44,14 @@ static struct drm_driver driver = {
*/ */
.driver_features = .driver_features =
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ 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, .load = i915_driver_load,
.lastclose = i915_driver_lastclose, .lastclose = i915_driver_lastclose,
.preclose = i915_driver_preclose, .preclose = i915_driver_preclose,
.device_is_agp = i915_driver_device_is_agp, .device_is_agp = i915_driver_device_is_agp,
.vblank_wait = i915_driver_vblank_wait, .vblank_wait = i915_driver_vblank_wait,
.vblank_wait2 = i915_driver_vblank_wait2,
.irq_preinstall = i915_driver_irq_preinstall, .irq_preinstall = i915_driver_irq_preinstall,
.irq_postinstall = i915_driver_irq_postinstall, .irq_postinstall = i915_driver_irq_postinstall,
.irq_uninstall = i915_driver_irq_uninstall, .irq_uninstall = i915_driver_irq_uninstall,
......
...@@ -117,6 +117,7 @@ extern int i915_irq_emit(DRM_IOCTL_ARGS); ...@@ -117,6 +117,7 @@ extern int i915_irq_emit(DRM_IOCTL_ARGS);
extern int i915_irq_wait(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_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 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
extern void i915_driver_irq_preinstall(drm_device_t * dev); extern void i915_driver_irq_preinstall(drm_device_t * dev);
extern void i915_driver_irq_postinstall(drm_device_t * dev); extern void i915_driver_irq_postinstall(drm_device_t * dev);
......
...@@ -60,7 +60,16 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) ...@@ -60,7 +60,16 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
DRM_WAKEUP(&dev_priv->irq_queue); DRM_WAKEUP(&dev_priv->irq_queue);
if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
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); 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_WAKEUP(&dev->vbl_queue);
drm_vbl_send_signals(dev); drm_vbl_send_signals(dev);
} }
...@@ -120,7 +129,8 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr) ...@@ -120,7 +129,8 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr)
return ret; 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; drm_i915_private_t *dev_priv = dev->dev_private;
unsigned int cur_vblank; unsigned int cur_vblank;
...@@ -132,7 +142,7 @@ int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) ...@@ -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, 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) <= (1<<23)));
*sequence = cur_vblank; *sequence = cur_vblank;
...@@ -141,6 +151,16 @@ int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) ...@@ -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. /* Needs the lock as it touches the ring.
*/ */
int i915_irq_emit(DRM_IOCTL_ARGS) int i915_irq_emit(DRM_IOCTL_ARGS)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment