Skip to content

Commit

Permalink
drm: add support for secondary vertical blank interrupt to i915
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
=?utf-8?q?Michel_D=C3=A4nzer?= authored and airlied committed Dec 7, 2006
1 parent 776c944 commit 68815ba
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
4 changes: 3 additions & 1 deletion drivers/char/drm/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/char/drm/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
26 changes: 23 additions & 3 deletions drivers/char/drm/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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)
Expand Down

0 comments on commit 68815ba

Please sign in to comment.