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 { | |||
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 | }; |
97 | enum fd_version fd_device_version(struct fd_device *dev); | 99 | enum 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 | ||
102 | struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); | 104 | struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); |
105 | struct fd_pipe * fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio); | ||
103 | void fd_pipe_del(struct fd_pipe *pipe); | 106 | void fd_pipe_del(struct fd_pipe *pipe); |
104 | int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, | 107 | int 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 | */ | ||
36 | struct fd_pipe * | 40 | struct fd_pipe * |
37 | fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) | 41 | fd_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 | ||
71 | struct fd_pipe * | ||
72 | fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) | ||
73 | { | ||
74 | return fd_pipe_new2(dev, id, 1); | ||
75 | } | ||
76 | |||
62 | void fd_pipe_del(struct fd_pipe *pipe) | 77 | void 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 | ||
212 | drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, | 213 | drm_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, | |||
103 | drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe, | 103 | drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe, |
104 | uint32_t timestamp); | 104 | uint32_t timestamp); |
105 | drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, | 105 | drm_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 | ||
108 | drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, | 108 | drm_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 | ||
103 | static 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 | |||
127 | static 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 | |||
100 | static void msm_pipe_destroy(struct fd_pipe *pipe) | 135 | static 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 | ||
124 | drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, | 160 | drm_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; |
161 | fail: | 200 | fail: |
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 | ||
61 | static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x) | 62 | 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) | |||
64 | } | 65 | } |
65 | 66 | ||
66 | drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, | 67 | drm_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 | ||
69 | drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, | 70 | drm_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; |