diff options
author | Dave Airlie <airlied@redhat.com> | 2016-09-28 11:09:59 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-09-28 11:09:59 +1000 |
commit | f8049dd865a1de8b494c16a4cd18ee15fa896810 (patch) | |
tree | 37b874acba1392e97864dc24692736210543a4e4 /drivers/gpu/drm/msm/msm_gem_submit.c | |
parent | 3f346d5dcb591c2a5a26653d093af710cf2e5a31 (diff) | |
parent | 7a3bcc0a8e2ad5fa7fe6d627e01c66b3488149b7 (diff) |
Merge branch 'msm-next' of git://people.freedesktop.org/~robclark/linux into drm-next
A bit smaller pull-req this time around. Some continued DT binding
cleanup to get the corresponding dts bits merged upstream (through
other trees). And explicit fence-fd support for submit ioctl.
* 'msm-next' of git://people.freedesktop.org/~robclark/linux:
drm/msm: bump kernel api version for explicit fencing
drm/msm: submit support for out-fences
drm/msm: move fence allocation out of msm_gpu_submit()
drm/msm: submit support for in-fences
drm/msm: extend the submit ioctl to pass in flags
drm/msm/mdp5: Set rotation property initial value to DRM_ROTATE_0 insted of 0
drm/msm/hdmi: don't print error when adding i2c adapter fails
drm/msm/mdp4: mark symbols static where possible
drm/msm: Remove call to reservation_object_test_signaled_rcu before wait
drm/msm/hdmi: Clean up HDMI gpio DT bindings
drm/msm/mdp4: Fix issue with LCDC/LVDS port parsing
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem_submit.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem_submit.c | 73 |
1 files changed, 68 insertions, 5 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 9766f9ae4b7d..3ac14cd1e5b9 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -15,6 +15,8 @@ * this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/sync_file.h> + #include "msm_drv.h" #include "msm_gpu.h" #include "msm_gem.h" @@ -361,6 +363,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct msm_file_private *ctx = file->driver_priv; struct msm_gem_submit *submit; struct msm_gpu *gpu = priv->gpu; + struct fence *in_fence = NULL; + struct sync_file *sync_file = NULL; + int out_fence_fd = -1; unsigned i; int ret; @@ -370,13 +375,24 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, /* for now, we just have 3d pipe.. eventually this would need to * be more clever to dispatch to appropriate gpu module: */ - if (args->pipe != MSM_PIPE_3D0) + if (MSM_PIPE_ID(args->flags) != MSM_PIPE_3D0) + return -EINVAL; + + if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS) return -EINVAL; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; + if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) { + out_fence_fd = get_unused_fd_flags(O_CLOEXEC); + if (out_fence_fd < 0) { + ret = out_fence_fd; + goto out_unlock; + } + } + submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); if (!submit) { ret = -ENOMEM; @@ -391,9 +407,32 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (ret) goto out; - ret = submit_fence_sync(submit); - if (ret) - goto out; + if (args->flags & MSM_SUBMIT_FENCE_FD_IN) { + in_fence = sync_file_get_fence(args->fence_fd); + + if (!in_fence) { + ret = -EINVAL; + goto out; + } + + /* TODO if we get an array-fence due to userspace merging multiple + * fences, we need a way to determine if all the backing fences + * are from our own context.. + */ + + if (in_fence->context != gpu->fctx->context) { + ret = fence_wait(in_fence, true); + if (ret) + goto out; + } + + } + + if (!(args->fence & MSM_SUBMIT_NO_IMPLICIT)) { + ret = submit_fence_sync(submit); + if (ret) + goto out; + } ret = submit_pin_objects(submit); if (ret) @@ -459,15 +498,39 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, submit->nr_cmds = i; - ret = msm_gpu_submit(gpu, submit, ctx); + submit->fence = msm_fence_alloc(gpu->fctx); + if (IS_ERR(submit->fence)) { + ret = PTR_ERR(submit->fence); + submit->fence = NULL; + goto out; + } + + if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) { + sync_file = sync_file_create(submit->fence); + if (!sync_file) { + ret = -ENOMEM; + goto out; + } + } + + msm_gpu_submit(gpu, submit, ctx); args->fence = submit->fence->seqno; + if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) { + fd_install(out_fence_fd, sync_file->file); + args->fence_fd = out_fence_fd; + } + out: + if (in_fence) + fence_put(in_fence); submit_cleanup(submit); if (ret) msm_gem_submit_free(submit); out_unlock: + if (ret && (out_fence_fd >= 0)) + put_unused_fd(out_fence_fd); mutex_unlock(&dev->struct_mutex); return ret; } |