diff --git a/src/freedreno/drm/msm/msm_pipe.c b/src/freedreno/drm/msm/msm_pipe.c index 65da676f4e9..6e519000938 100644 --- a/src/freedreno/drm/msm/msm_pipe.c +++ b/src/freedreno/drm/msm/msm_pipe.c @@ -137,10 +137,10 @@ msm_pipe_wait(struct fd_pipe *pipe, const struct fd_fence *fence, uint64_t timeo } static int -open_submitqueue(struct fd_pipe *pipe, uint32_t prio) +__open_submitqueue(struct fd_pipe *pipe, uint32_t prio, uint32_t flags) { struct drm_msm_submitqueue req = { - .flags = 0, + .flags = flags, .prio = prio, }; uint64_t nr_prio = 1; @@ -157,12 +157,31 @@ open_submitqueue(struct fd_pipe *pipe, uint32_t prio) ret = drmCommandWriteRead(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_NEW, &req, sizeof(req)); + if (ret) + return ret; + + to_msm_pipe(pipe)->queue_id = req.id; + return 0; +} + +static int +open_submitqueue(struct fd_pipe *pipe, uint32_t prio) +{ + const struct fd_dev_info *info = fd_dev_info_raw(&pipe->dev_id); + int ret = -1; + + if (info && info->chip >= A7XX) + ret = __open_submitqueue(pipe, prio, MSM_SUBMITQUEUE_ALLOW_PREEMPT); + + /* If kernel doesn't support preemption, try again without: */ + if (ret) + ret = __open_submitqueue(pipe, prio, 0); + if (ret) { ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno)); return ret; } - to_msm_pipe(pipe)->queue_id = req.id; return 0; } diff --git a/src/freedreno/drm/virtio/virtio_pipe.c b/src/freedreno/drm/virtio/virtio_pipe.c index 6e1501389ea..cdeb9139f91 100644 --- a/src/freedreno/drm/virtio/virtio_pipe.c +++ b/src/freedreno/drm/virtio/virtio_pipe.c @@ -148,12 +148,12 @@ out: } static int -open_submitqueue(struct fd_pipe *pipe, uint32_t prio) +__open_submitqueue(struct fd_pipe *pipe, uint32_t prio, uint32_t flags) { struct virtio_pipe *virtio_pipe = to_virtio_pipe(pipe); struct drm_msm_submitqueue req = { - .flags = 0, + .flags = flags, .prio = prio, }; uint64_t nr_prio = 1; @@ -175,6 +175,27 @@ open_submitqueue(struct fd_pipe *pipe, uint32_t prio) return 0; } +static int +open_submitqueue(struct fd_pipe *pipe, uint32_t prio) +{ + const struct fd_dev_info *info = fd_dev_info_raw(&pipe->dev_id); + int ret = -1; + + if (info && info->chip >= A7XX) + ret = __open_submitqueue(pipe, prio, MSM_SUBMITQUEUE_ALLOW_PREEMPT); + + /* If kernel doesn't support preemption, try again without: */ + if (ret) + ret = __open_submitqueue(pipe, prio, 0); + + if (ret) { + ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno)); + return ret; + } + + return 0; +} + static void close_submitqueue(struct fd_pipe *pipe, uint32_t queue_id) {