drm: i915 updates
Add support for DRM_VBLANK_NEXTONMISS. Bump minor for swap scheduling ioctl and secondary vblank support. Avoid mis-counting vblank interrupts when they're only enabled for pipe A. Only schedule vblank tasklet if there are scheduled swaps pending. Signed-off-by: Dave Airlie <airlied@linux.ie>
This commit is contained in:
parent
a0b136bb69
commit
2228ed6722
2 changed files with 21 additions and 19 deletions
|
@ -46,9 +46,11 @@
|
|||
* 1.3: Add vblank support
|
||||
* 1.4: Fix cmdbuffer path, add heap destroy
|
||||
* 1.5: Add vblank pipe configuration
|
||||
* 1.6: - New ioctl for scheduling buffer swaps on vertical blank
|
||||
* - Support vertical blank on secondary display pipe
|
||||
*/
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 5
|
||||
#define DRIVER_MINOR 6
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
typedef struct _drm_i915_ring_buffer {
|
||||
|
|
|
@ -153,20 +153,26 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
DRM_WAKEUP(&dev_priv->irq_queue);
|
||||
|
||||
if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
|
||||
if ((dev_priv->vblank_pipe &
|
||||
int vblank_pipe = dev_priv->vblank_pipe;
|
||||
|
||||
if ((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
|
||||
} else if (((temp & VSYNC_PIPEA_FLAG) &&
|
||||
(vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
|
||||
((temp & VSYNC_PIPEB_FLAG) &&
|
||||
(vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
|
||||
atomic_inc(&dev->vbl_received);
|
||||
|
||||
DRM_WAKEUP(&dev->vbl_queue);
|
||||
drm_vbl_send_signals(dev);
|
||||
|
||||
drm_locked_tasklet(dev, i915_vblank_tasklet);
|
||||
if (dev_priv->swaps_pending > 0)
|
||||
drm_locked_tasklet(dev, i915_vblank_tasklet);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
@ -397,7 +403,7 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
|
|||
sizeof(swap));
|
||||
|
||||
if (swap.seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE |
|
||||
_DRM_VBLANK_SECONDARY)) {
|
||||
_DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) {
|
||||
DRM_ERROR("Invalid sequence type 0x%x\n", swap.seqtype);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
@ -406,11 +412,6 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
|
|||
|
||||
seqtype = swap.seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
|
||||
|
||||
if (seqtype == _DRM_VBLANK_RELATIVE && swap.sequence == 0) {
|
||||
DRM_DEBUG("Not scheduling swap for current sequence\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
if (!(dev_priv->vblank_pipe & (1 << pipe))) {
|
||||
DRM_ERROR("Invalid pipe %d\n", pipe);
|
||||
return DRM_ERR(EINVAL);
|
||||
|
@ -428,21 +429,20 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
|
|||
|
||||
curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
|
||||
|
||||
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
|
||||
|
||||
switch (seqtype) {
|
||||
case _DRM_VBLANK_RELATIVE:
|
||||
if (seqtype == _DRM_VBLANK_RELATIVE)
|
||||
swap.sequence += curseq;
|
||||
break;
|
||||
case _DRM_VBLANK_ABSOLUTE:
|
||||
if ((curseq - swap.sequence) <= (1<<23)) {
|
||||
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
|
||||
|
||||
if ((curseq - swap.sequence) <= (1<<23)) {
|
||||
if (swap.seqtype & _DRM_VBLANK_NEXTONMISS) {
|
||||
swap.sequence = curseq + 1;
|
||||
} else {
|
||||
DRM_DEBUG("Missed target sequence\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
|
||||
|
||||
list_for_each(list, &dev_priv->vbl_swaps.head) {
|
||||
vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
|
||||
|
||||
|
|
Loading…
Reference in a new issue