summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/msm_gem_submit.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-09-28 11:09:59 +1000
committerDave Airlie <airlied@redhat.com>2016-09-28 11:09:59 +1000
commitf8049dd865a1de8b494c16a4cd18ee15fa896810 (patch)
tree37b874acba1392e97864dc24692736210543a4e4 /drivers/gpu/drm/msm/msm_gem_submit.c
parent3f346d5dcb591c2a5a26653d093af710cf2e5a31 (diff)
parent7a3bcc0a8e2ad5fa7fe6d627e01c66b3488149b7 (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.c73
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;
}