diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index a3d33a5..ac2fe5a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -466,6 +466,35 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, return 0; } +int +nouveau_ioctl_fifo_wait(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct nouveau_fence *fence = NULL; + struct drm_nouveau_channel_wait *req = data; + struct nouveau_channel *chan; + int ret = 0; + + chan = nouveau_channel_get(dev, file_priv, req->channel); + if (IS_ERR(chan)) + return PTR_ERR(chan); + + nouveau_fence_update(chan); + + if (chan->fence.sequence != chan->fence.sequence_ack) { + ret = nouveau_fence_new(chan, &fence, true); + if (!ret) { + ret = nouveau_fence_wait(fence, true, true); + nouveau_fence_unref(&fence); + } + + if (ret) + NV_ERROR(dev, "Error during nouveau_ioctl_fifo_wait %d.\n", chan- >id); + } + nouveau_channel_put(&chan); + return ret; +} + /*********************************** * finally, the ioctl table ***********************************/ @@ -475,6 +504,7 @@ struct drm_ioctl_desc nouveau_ioctls[] = { DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_UNLOCKED| DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_UNLOCKED|DRM_AUTH), DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_WAIT, nouveau_ioctl_fifo_wait, DRM_UNLOCKED|DRM_AUTH), DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH), DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_UNLOCKED|DRM_AUTH), DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH), diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 0fa6bdb..7713fef09 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1308,6 +1308,7 @@ extern int __nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr); extern int __nouveau_fence_flush(void *obj, void *arg); extern void __nouveau_fence_unref(void **obj); extern void *__nouveau_fence_ref(void *obj); +extern int nouveau_fence_channel_wait(struct nouveau_channel *chan); static inline bool nouveau_fence_signalled(struct nouveau_fence *obj) { diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 374a979..140b48a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -504,6 +504,25 @@ nouveau_fence_channel_fini(struct nouveau_channel *chan) } int +nouveau_fence_channel_wait(struct nouveau_channel *chan) +{ + int ret = 0; + struct nouveau_fence *tmp; + struct drm_device *dev = chan->dev; + int seq; + + if (list_empty_careful(&chan->fence.pending)) + return 0; + tmp = list_entry(chan->fence.pending.prev, struct nouveau_fence, entry); + seq = tmp->sequence; + nouveau_fence_ref(tmp); + ret = __nouveau_fence_wait(tmp, NULL, true, true); + nouveau_fence_unref(&tmp); + + return ret; +} + +int nouveau_fence_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index f9b259e..459abd7 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -49,6 +49,10 @@ struct drm_nouveau_channel_free { int channel; }; +struct drm_nouveau_channel_wait { + int channel; +}; + struct drm_nouveau_grobj_alloc { int channel; uint32_t handle; @@ -201,6 +205,7 @@ struct drm_nouveau_sarea { #define DRM_NOUVEAU_GEM_CPU_PREP 0x42 #define DRM_NOUVEAU_GEM_CPU_FINI 0x43 #define DRM_NOUVEAU_GEM_INFO 0x44 +#define DRM_NOUVEAU_CHANNEL_WAIT 0x45 #define DRM_IOCTL_NOUVEAU_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GETPARAM, struct drm_nouveau_getparam) #define DRM_IOCTL_NOUVEAU_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_SETPARAM, struct drm_nouveau_setparam) @@ -214,5 +219,6 @@ struct drm_nouveau_sarea { #define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep) #define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini) #define DRM_IOCTL_NOUVEAU_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info) +#define DRM_IOCTL_NOUVEAU_CHANNEL_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_CHANNEL_WAIT, struct drm_nouveau_channel_wait) #endif /* __NOUVEAU_DRM_H__ */ _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev