aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark2017-08-23 16:08:39 -0500
committerRob Clark2017-11-04 16:23:20 -0500
commit7064b2eae9c136162e5c7f25571d63f71d066887 (patch)
tree6c5a1c056465be9af38b1bce6904999d839288f0 /freedreno
parent62e0767b816cb52b35226d439090ef580bd60b01 (diff)
downloadexternal-libdrm-7064b2eae9c136162e5c7f25571d63f71d066887.tar.gz
external-libdrm-7064b2eae9c136162e5c7f25571d63f71d066887.tar.xz
external-libdrm-7064b2eae9c136162e5c7f25571d63f71d066887.zip
freedreno: submit-queue context priority
With a new-enough kernel to support prioritized submit-queues, we can expose priority level support to mesa. Open a submit queue associated with the fd_pipe and pass it's id back to SUBMIT ioctl. Signed-off-by: Rob Clark <robclark@freedesktop.org>
Diffstat (limited to 'freedreno')
-rw-r--r--freedreno/freedreno_drmif.h3
-rw-r--r--freedreno/freedreno_pipe.c19
-rw-r--r--freedreno/freedreno_priv.h3
-rw-r--r--freedreno/kgsl/kgsl_pipe.c3
-rw-r--r--freedreno/kgsl/kgsl_priv.h2
-rw-r--r--freedreno/msm/msm_pipe.c41
-rw-r--r--freedreno/msm/msm_priv.h3
-rw-r--r--freedreno/msm/msm_ringbuffer.c1
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 {
61 FD_CHIP_ID, 61 FD_CHIP_ID,
62 FD_MAX_FREQ, 62 FD_MAX_FREQ,
63 FD_TIMESTAMP, 63 FD_TIMESTAMP,
64 FD_NR_RINGS, /* # of rings == # of distinct priority levels */
64}; 65};
65 66
66/* bo flags: */ 67/* bo flags: */
@@ -93,6 +94,7 @@ enum fd_version {
93 FD_VERSION_MADVISE = 1, /* kernel supports madvise */ 94 FD_VERSION_MADVISE = 1, /* kernel supports madvise */
94 FD_VERSION_UNLIMITED_CMDS = 1, /* submits w/ >4 cmd buffers (growable ringbuffer) */ 95 FD_VERSION_UNLIMITED_CMDS = 1, /* submits w/ >4 cmd buffers (growable ringbuffer) */
95 FD_VERSION_FENCE_FD = 2, /* submit command supports in/out fences */ 96 FD_VERSION_FENCE_FD = 2, /* submit command supports in/out fences */
97 FD_VERSION_SUBMIT_QUEUES = 3, /* submit queues and multiple priority levels */
96}; 98};
97enum fd_version fd_device_version(struct fd_device *dev); 99enum fd_version fd_device_version(struct fd_device *dev);
98 100
@@ -100,6 +102,7 @@ enum fd_version fd_device_version(struct fd_device *dev);
100 */ 102 */
101 103
102struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); 104struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id);
105struct fd_pipe * fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio);
103void fd_pipe_del(struct fd_pipe *pipe); 106void fd_pipe_del(struct fd_pipe *pipe);
104int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, 107int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param,
105 uint64_t *value); 108 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 @@
33#include "freedreno_drmif.h" 33#include "freedreno_drmif.h"
34#include "freedreno_priv.h" 34#include "freedreno_priv.h"
35 35
36/**
37 * priority of zero is highest priority, and higher numeric values are
38 * lower priorities
39 */
36struct fd_pipe * 40struct fd_pipe *
37fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) 41fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio)
38{ 42{
39 struct fd_pipe *pipe; 43 struct fd_pipe *pipe;
40 uint64_t val; 44 uint64_t val;
@@ -44,7 +48,12 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
44 return NULL; 48 return NULL;
45 } 49 }
46 50
47 pipe = dev->funcs->pipe_new(dev, id); 51 if ((prio != 1) && (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES)) {
52 ERROR_MSG("invalid priority!");
53 return NULL;
54 }
55
56 pipe = dev->funcs->pipe_new(dev, id, prio);
48 if (!pipe) { 57 if (!pipe) {
49 ERROR_MSG("allocation failed"); 58 ERROR_MSG("allocation failed");
50 return NULL; 59 return NULL;
@@ -59,6 +68,12 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
59 return pipe; 68 return pipe;
60} 69}
61 70
71struct fd_pipe *
72fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
73{
74 return fd_pipe_new2(dev, id, 1);
75}
76
62void fd_pipe_del(struct fd_pipe *pipe) 77void fd_pipe_del(struct fd_pipe *pipe)
63{ 78{
64 pipe->funcs->destroy(pipe); 79 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 {
66 uint32_t flags, uint32_t *handle); 66 uint32_t flags, uint32_t *handle);
67 struct fd_bo * (*bo_from_handle)(struct fd_device *dev, 67 struct fd_bo * (*bo_from_handle)(struct fd_device *dev,
68 uint32_t size, uint32_t handle); 68 uint32_t size, uint32_t handle);
69 struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id); 69 struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id,
70 unsigned prio);
70 void (*destroy)(struct fd_device *dev); 71 void (*destroy)(struct fd_device *dev);
71}; 72};
72 73
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,
52 return 0; 52 return 0;
53 case FD_MAX_FREQ: 53 case FD_MAX_FREQ:
54 case FD_TIMESTAMP: 54 case FD_TIMESTAMP:
55 case FD_NR_RINGS:
55 /* unsupported on kgsl */ 56 /* unsupported on kgsl */
56 return -1; 57 return -1;
57 default: 58 default:
@@ -210,7 +211,7 @@ static int getprop(int fd, enum kgsl_property_type type,
210 211
211 212
212drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, 213drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
213 enum fd_pipe_id id) 214 enum fd_pipe_id id, uint32_t prio)
214{ 215{
215 static const char *paths[] = { 216 static const char *paths[] = {
216 [FD_PIPE_3D] = "/dev/kgsl-3d0", 217 [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,
103drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe, 103drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe,
104 uint32_t timestamp); 104 uint32_t timestamp);
105drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, 105drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
106 enum fd_pipe_id id); 106 enum fd_pipe_id id, uint32_t prio);
107 107
108drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, 108drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
109 uint32_t size); 109 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,
71 return query_param(pipe, MSM_PARAM_MAX_FREQ, value); 71 return query_param(pipe, MSM_PARAM_MAX_FREQ, value);
72 case FD_TIMESTAMP: 72 case FD_TIMESTAMP:
73 return query_param(pipe, MSM_PARAM_TIMESTAMP, value); 73 return query_param(pipe, MSM_PARAM_TIMESTAMP, value);
74 case FD_NR_RINGS:
75 return query_param(pipe, MSM_PARAM_NR_RINGS, value);
74 default: 76 default:
75 ERROR_MSG("invalid param id: %d", param); 77 ERROR_MSG("invalid param id: %d", param);
76 return -1; 78 return -1;
@@ -83,6 +85,7 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
83 struct fd_device *dev = pipe->dev; 85 struct fd_device *dev = pipe->dev;
84 struct drm_msm_wait_fence req = { 86 struct drm_msm_wait_fence req = {
85 .fence = timestamp, 87 .fence = timestamp,
88 .queueid = to_msm_pipe(pipe)->queue_id,
86 }; 89 };
87 int ret; 90 int ret;
88 91
@@ -97,9 +100,42 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
97 return 0; 100 return 0;
98} 101}
99 102
103static int open_submitqueue(struct fd_device *dev, uint32_t prio,
104 uint32_t *queue_id)
105{
106 struct drm_msm_submitqueue req = {
107 .flags = 0,
108 .prio = prio,
109 };
110 int ret;
111
112 if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES) {
113 *queue_id = 0;
114 return 0;
115 }
116
117 ret = drmCommandWriteRead(dev->fd, DRM_MSM_SUBMITQUEUE_NEW, &req, sizeof(req));
118 if (ret) {
119 ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno));
120 return ret;
121 }
122
123 *queue_id = req.id;
124 return 0;
125}
126
127static void close_submitqueue(struct fd_device *dev, uint32_t queue_id)
128{
129 if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES)
130 return;
131
132 drmCommandWrite(dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE, &queue_id, sizeof(queue_id));
133}
134
100static void msm_pipe_destroy(struct fd_pipe *pipe) 135static void msm_pipe_destroy(struct fd_pipe *pipe)
101{ 136{
102 struct msm_pipe *msm_pipe = to_msm_pipe(pipe); 137 struct msm_pipe *msm_pipe = to_msm_pipe(pipe);
138 close_submitqueue(pipe->dev, msm_pipe->queue_id);
103 free(msm_pipe); 139 free(msm_pipe);
104} 140}
105 141
@@ -122,7 +158,7 @@ static uint64_t get_param(struct fd_pipe *pipe, uint32_t param)
122} 158}
123 159
124drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, 160drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
125 enum fd_pipe_id id) 161 enum fd_pipe_id id, uint32_t prio)
126{ 162{
127 static const uint32_t pipe_id[] = { 163 static const uint32_t pipe_id[] = {
128 [FD_PIPE_3D] = MSM_PIPE_3D0, 164 [FD_PIPE_3D] = MSM_PIPE_3D0,
@@ -157,6 +193,9 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
157 INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id); 193 INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id);
158 INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem); 194 INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem);
159 195
196 if (open_submitqueue(dev, prio, &msm_pipe->queue_id))
197 goto fail;
198
160 return pipe; 199 return pipe;
161fail: 200fail:
162 if (pipe) 201 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 {
56 uint32_t gpu_id; 56 uint32_t gpu_id;
57 uint32_t gmem; 57 uint32_t gmem;
58 uint32_t chip_id; 58 uint32_t chip_id;
59 uint32_t queue_id;
59}; 60};
60 61
61static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x) 62static 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)
64} 65}
65 66
66drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, 67drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
67 enum fd_pipe_id id); 68 enum fd_pipe_id id, uint32_t prio);
68 69
69drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, 70drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
70 uint32_t size); 71 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
401 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 401 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
402 struct drm_msm_gem_submit req = { 402 struct drm_msm_gem_submit req = {
403 .flags = to_msm_pipe(ring->pipe)->pipe, 403 .flags = to_msm_pipe(ring->pipe)->pipe,
404 .queueid = to_msm_pipe(ring->pipe)->queue_id,
404 }; 405 };
405 uint32_t i; 406 uint32_t i;
406 int ret; 407 int ret;