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>
This commit is contained in:
parent
776c9443e2
commit
68815bad72
|
@ -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);
|
||||||
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)
|
||||||
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)) {
|
||||||
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_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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
Loading…
Reference in New Issue