diff options
Diffstat (limited to 'freedreno')
-rw-r--r-- | freedreno/freedreno_drmif.h | 3 | ||||
-rw-r--r-- | freedreno/freedreno_pipe.c | 19 | ||||
-rw-r--r-- | freedreno/freedreno_priv.h | 3 | ||||
-rw-r--r-- | freedreno/kgsl/kgsl_pipe.c | 3 | ||||
-rw-r--r-- | freedreno/kgsl/kgsl_priv.h | 2 | ||||
-rw-r--r-- | freedreno/msm/msm_pipe.c | 41 | ||||
-rw-r--r-- | freedreno/msm/msm_priv.h | 3 | ||||
-rw-r--r-- | freedreno/msm/msm_ringbuffer.c | 1 |
8 files changed, 68 insertions, 7 deletions
diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h index 7a8073ff..c3b0d02a 100644 --- a/freedreno/freedreno_drmif.h +++ b/freedreno/freedreno_drmif.h @@ -61,6 +61,7 @@ enum fd_param_id { FD_CHIP_ID, FD_MAX_FREQ, FD_TIMESTAMP, + FD_NR_RINGS, /* # of rings == # of distinct priority levels */ }; /* bo flags: */ @@ -93,6 +94,7 @@ enum fd_version { FD_VERSION_MADVISE = 1, /* kernel supports madvise */ FD_VERSION_UNLIMITED_CMDS = 1, /* submits w/ >4 cmd buffers (growable ringbuffer) */ FD_VERSION_FENCE_FD = 2, /* submit command supports in/out fences */ + FD_VERSION_SUBMIT_QUEUES = 3, /* submit queues and multiple priority levels */ }; enum fd_version fd_device_version(struct fd_device *dev); @@ -100,6 +102,7 @@ enum fd_version fd_device_version(struct fd_device *dev); */ struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); +struct fd_pipe * fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio); void fd_pipe_del(struct fd_pipe *pipe); int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value); diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c index e69cb28c..1540474b 100644 --- a/freedreno/freedreno_pipe.c +++ b/freedreno/freedreno_pipe.c @@ -33,8 +33,12 @@ #include "freedreno_drmif.h" #include "freedreno_priv.h" +/** + * priority of zero is highest priority, and higher numeric values are + * lower priorities + */ struct fd_pipe * -fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) +fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio) { struct fd_pipe *pipe; uint64_t val; @@ -44,7 +48,12 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) return NULL; } - pipe = dev->funcs->pipe_new(dev, id); + if ((prio != 1) && (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES)) { + ERROR_MSG("invalid priority!"); + return NULL; + } + + pipe = dev->funcs->pipe_new(dev, id, prio); if (!pipe) { ERROR_MSG("allocation failed"); return NULL; @@ -59,6 +68,12 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) return pipe; } +struct fd_pipe * +fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) +{ + return fd_pipe_new2(dev, id, 1); +} + void fd_pipe_del(struct fd_pipe *pipe) { pipe->funcs->destroy(pipe); diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h index 8dd3ee69..27307472 100644 --- a/freedreno/freedreno_priv.h +++ b/freedreno/freedreno_priv.h @@ -66,7 +66,8 @@ struct fd_device_funcs { uint32_t flags, uint32_t *handle); struct fd_bo * (*bo_from_handle)(struct fd_device *dev, uint32_t size, uint32_t handle); - struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id); + struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id, + unsigned prio); void (*destroy)(struct fd_device *dev); }; diff --git a/freedreno/kgsl/kgsl_pipe.c b/freedreno/kgsl/kgsl_pipe.c index 8a39eb49..80bd1313 100644 --- a/freedreno/kgsl/kgsl_pipe.c +++ b/freedreno/kgsl/kgsl_pipe.c @@ -52,6 +52,7 @@ static int kgsl_pipe_get_param(struct fd_pipe *pipe, return 0; case FD_MAX_FREQ: case FD_TIMESTAMP: + case FD_NR_RINGS: /* unsupported on kgsl */ return -1; default: @@ -210,7 +211,7 @@ static int getprop(int fd, enum kgsl_property_type type, drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, - enum fd_pipe_id id) + enum fd_pipe_id id, uint32_t prio) { static const char *paths[] = { [FD_PIPE_3D] = "/dev/kgsl-3d0", diff --git a/freedreno/kgsl/kgsl_priv.h b/freedreno/kgsl/kgsl_priv.h index 6ab64965..41b13920 100644 --- a/freedreno/kgsl/kgsl_priv.h +++ b/freedreno/kgsl/kgsl_priv.h @@ -103,7 +103,7 @@ drm_private void kgsl_pipe_post_submit(struct kgsl_pipe *pipe, drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe, uint32_t timestamp); drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, - enum fd_pipe_id id); + enum fd_pipe_id id, uint32_t prio); drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, uint32_t size); diff --git a/freedreno/msm/msm_pipe.c b/freedreno/msm/msm_pipe.c index f872e245..7395e573 100644 --- a/freedreno/msm/msm_pipe.c +++ b/freedreno/msm/msm_pipe.c @@ -71,6 +71,8 @@ static int msm_pipe_get_param(struct fd_pipe *pipe, return query_param(pipe, MSM_PARAM_MAX_FREQ, value); case FD_TIMESTAMP: return query_param(pipe, MSM_PARAM_TIMESTAMP, value); + case FD_NR_RINGS: + return query_param(pipe, MSM_PARAM_NR_RINGS, value); default: ERROR_MSG("invalid param id: %d", param); return -1; @@ -83,6 +85,7 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp, struct fd_device *dev = pipe->dev; struct drm_msm_wait_fence req = { .fence = timestamp, + .queueid = to_msm_pipe(pipe)->queue_id, }; int ret; @@ -97,9 +100,42 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp, return 0; } +static int open_submitqueue(struct fd_device *dev, uint32_t prio, + uint32_t *queue_id) +{ + struct drm_msm_submitqueue req = { + .flags = 0, + .prio = prio, + }; + int ret; + + if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES) { + *queue_id = 0; + return 0; + } + + ret = drmCommandWriteRead(dev->fd, DRM_MSM_SUBMITQUEUE_NEW, &req, sizeof(req)); + if (ret) { + ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno)); + return ret; + } + + *queue_id = req.id; + return 0; +} + +static void close_submitqueue(struct fd_device *dev, uint32_t queue_id) +{ + if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES) + return; + + drmCommandWrite(dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE, &queue_id, sizeof(queue_id)); +} + static void msm_pipe_destroy(struct fd_pipe *pipe) { struct msm_pipe *msm_pipe = to_msm_pipe(pipe); + close_submitqueue(pipe->dev, msm_pipe->queue_id); free(msm_pipe); } @@ -122,7 +158,7 @@ static uint64_t get_param(struct fd_pipe *pipe, uint32_t param) } drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, - enum fd_pipe_id id) + enum fd_pipe_id id, uint32_t prio) { static const uint32_t pipe_id[] = { [FD_PIPE_3D] = MSM_PIPE_3D0, @@ -157,6 +193,9 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id); INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem); + if (open_submitqueue(dev, prio, &msm_pipe->queue_id)) + goto fail; + return pipe; fail: if (pipe) diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h index 6d670aab..88ac3aa4 100644 --- a/freedreno/msm/msm_priv.h +++ b/freedreno/msm/msm_priv.h @@ -56,6 +56,7 @@ struct msm_pipe { uint32_t gpu_id; uint32_t gmem; uint32_t chip_id; + uint32_t queue_id; }; static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x) @@ -64,7 +65,7 @@ static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x) } drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, - enum fd_pipe_id id); + enum fd_pipe_id id, uint32_t prio); drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, uint32_t size); diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c index 5b28feaa..c75bb169 100644 --- a/freedreno/msm/msm_ringbuffer.c +++ b/freedreno/msm/msm_ringbuffer.c @@ -401,6 +401,7 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); struct drm_msm_gem_submit req = { .flags = to_msm_pipe(ring->pipe)->pipe, + .queueid = to_msm_pipe(ring->pipe)->queue_id, }; uint32_t i; int ret; |