From e6654907755f745f73f830fec0637c27ed98331e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=3D=3Futf-8=3Fq=3FMichel=5FD=3DC3=3DA4nzer=3F=3D?= Date: Tue, 24 Oct 2006 23:38:54 +1000 Subject: [PATCH] --- yaml --- r: 43915 b: refs/heads/master c: 541f29aad766b6c7b911a7d900d952744369bf53 h: refs/heads/master i: 43913: 189a3e47b6ab17e707a9022d9d72c589c2d928ff 43911: bc9e90b9b0609fc11f7d315546826565b4a3b50b v: v3 --- [refs] | 2 +- trunk/drivers/char/drm/i915_drm.h | 3 ++- trunk/drivers/char/drm/i915_irq.c | 43 +++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index b22123041d96..a3d2e3e8298c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a6b54f3f5050c0cbc0c35dd48064846c6302706b +refs/heads/master: 541f29aad766b6c7b911a7d900d952744369bf53 diff --git a/trunk/drivers/char/drm/i915_drm.h b/trunk/drivers/char/drm/i915_drm.h index 8926beb5a61f..4ce3d16cf065 100644 --- a/trunk/drivers/char/drm/i915_drm.h +++ b/trunk/drivers/char/drm/i915_drm.h @@ -149,6 +149,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) +#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -248,7 +249,7 @@ typedef struct drm_i915_vblank_pipe { */ typedef struct drm_i915_vblank_swap { drm_drawable_t drawable; - unsigned int pipe; + drm_vblank_seq_type_t seqtype; unsigned int sequence; } drm_i915_vblank_swap_t; diff --git a/trunk/drivers/char/drm/i915_irq.c b/trunk/drivers/char/drm/i915_irq.c index a93f1f37ec6a..d56455666312 100644 --- a/trunk/drivers/char/drm/i915_irq.c +++ b/trunk/drivers/char/drm/i915_irq.c @@ -375,7 +375,7 @@ int i915_vblank_swap(DRM_IOCTL_ARGS) drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_vblank_swap_t swap; drm_i915_vbl_swap_t *vbl_swap; - unsigned int irqflags; + unsigned int pipe, seqtype, irqflags, curseq; struct list_head *list; if (!dev_priv) { @@ -396,8 +396,23 @@ int i915_vblank_swap(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(swap, (drm_i915_vblank_swap_t __user *) data, sizeof(swap)); - if (swap.pipe > 1 || !(dev_priv->vblank_pipe & (1 << swap.pipe))) { - DRM_ERROR("Invalid pipe %d\n", swap.pipe); + if (swap.seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | + _DRM_VBLANK_SECONDARY)) { + DRM_ERROR("Invalid sequence type 0x%x\n", swap.seqtype); + return DRM_ERR(EINVAL); + } + + pipe = (swap.seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; + + 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); } @@ -411,13 +426,28 @@ int i915_vblank_swap(DRM_IOCTL_ARGS) spin_unlock_irqrestore(&dev->drw_lock, irqflags); + curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received); + spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); + switch (seqtype) { + case _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); + DRM_DEBUG("Missed target sequence\n"); + return DRM_ERR(EINVAL); + } + break; + } + list_for_each(list, &dev_priv->vbl_swaps.head) { vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); if (vbl_swap->drw_id == swap.drawable && - vbl_swap->pipe == swap.pipe && + vbl_swap->pipe == pipe && vbl_swap->sequence == swap.sequence) { spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); DRM_DEBUG("Already scheduled\n"); @@ -437,7 +467,7 @@ int i915_vblank_swap(DRM_IOCTL_ARGS) DRM_DEBUG("\n"); vbl_swap->drw_id = swap.drawable; - vbl_swap->pipe = swap.pipe; + vbl_swap->pipe = pipe; vbl_swap->sequence = swap.sequence; spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); @@ -447,6 +477,9 @@ int i915_vblank_swap(DRM_IOCTL_ARGS) spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); + DRM_COPY_TO_USER_IOCTL((drm_i915_vblank_swap_t __user *) data, swap, + sizeof(swap)); + return 0; }