diff options
author | John Stultz | 2018-04-13 18:31:33 -0500 |
---|---|---|
committer | John Stultz | 2018-04-13 18:31:33 -0500 |
commit | 84f838d71a75125b14d361f0ed7d23a0ac521edf (patch) | |
tree | a7694dfdab2ca2b1d32e25071589c7ea0a992bd6 /freedreno | |
parent | 2f9aea0661550a43c3d2ac33a5bc286870edd34e (diff) | |
parent | 35affe89d5f617a972b1cfee00c51cbe9e7c64a2 (diff) | |
download | external-libdrm-84f838d71a75125b14d361f0ed7d23a0ac521edf.tar.gz external-libdrm-84f838d71a75125b14d361f0ed7d23a0ac521edf.tar.xz external-libdrm-84f838d71a75125b14d361f0ed7d23a0ac521edf.zip |
Merge remote-tracking branch 'freedesktop/master' into aosp/master
This merges the freedesktop/master branch into aosp/master
Change-Id: I3104d45924f67d37808154d04c15518394204478
Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'freedreno')
-rw-r--r-- | freedreno/Makefile.am | 1 | ||||
-rwxr-xr-x | freedreno/freedreno-symbol-check | 5 | ||||
-rw-r--r-- | freedreno/freedreno_bo.c | 29 | ||||
-rw-r--r-- | freedreno/freedreno_bo_cache.c | 8 | ||||
-rw-r--r-- | freedreno/freedreno_device.c | 11 | ||||
-rw-r--r-- | freedreno/freedreno_drmif.h | 6 | ||||
-rw-r--r-- | freedreno/freedreno_pipe.c | 33 | ||||
-rw-r--r-- | freedreno/freedreno_priv.h | 66 | ||||
-rw-r--r-- | freedreno/freedreno_ringbuffer.c | 4 | ||||
-rw-r--r-- | freedreno/kgsl/kgsl_bo.c | 4 | ||||
-rw-r--r-- | freedreno/kgsl/kgsl_device.c | 6 | ||||
-rw-r--r-- | freedreno/kgsl/kgsl_pipe.c | 7 | ||||
-rw-r--r-- | freedreno/kgsl/kgsl_priv.h | 2 | ||||
-rw-r--r-- | freedreno/kgsl/kgsl_ringbuffer.c | 6 | ||||
-rw-r--r-- | freedreno/meson.build | 77 | ||||
-rw-r--r-- | freedreno/msm/msm_bo.c | 17 | ||||
-rw-r--r-- | freedreno/msm/msm_device.c | 6 | ||||
-rw-r--r-- | freedreno/msm/msm_drm.h | 40 | ||||
-rw-r--r-- | freedreno/msm/msm_pipe.c | 51 | ||||
-rw-r--r-- | freedreno/msm/msm_priv.h | 3 | ||||
-rw-r--r-- | freedreno/msm/msm_ringbuffer.c | 20 |
21 files changed, 310 insertions, 92 deletions
diff --git a/freedreno/Makefile.am b/freedreno/Makefile.am index 0771d146..cbb0d031 100644 --- a/freedreno/Makefile.am +++ b/freedreno/Makefile.am | |||
@@ -5,6 +5,7 @@ AM_CFLAGS = \ | |||
5 | $(WARN_CFLAGS) \ | 5 | $(WARN_CFLAGS) \ |
6 | -I$(top_srcdir) \ | 6 | -I$(top_srcdir) \ |
7 | $(PTHREADSTUBS_CFLAGS) \ | 7 | $(PTHREADSTUBS_CFLAGS) \ |
8 | $(VALGRIND_CFLAGS) \ | ||
8 | -I$(top_srcdir)/include/drm | 9 | -I$(top_srcdir)/include/drm |
9 | 10 | ||
10 | libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la | 11 | libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la |
diff --git a/freedreno/freedreno-symbol-check b/freedreno/freedreno-symbol-check index 42f2c439..3b119528 100755 --- a/freedreno/freedreno-symbol-check +++ b/freedreno/freedreno-symbol-check | |||
@@ -3,7 +3,7 @@ | |||
3 | # The following symbols (past the first five) are taken from the public headers. | 3 | # The following symbols (past the first five) are taken from the public headers. |
4 | # A list of the latter should be available Makefile.sources/LIBDRM_FREEDRENO_H_FILES | 4 | # A list of the latter should be available Makefile.sources/LIBDRM_FREEDRENO_H_FILES |
5 | 5 | ||
6 | FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_freedreno.so} | awk '{print $3}'| while read func; do | 6 | FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_freedreno.so} | awk '{print $3}'| while read func; do |
7 | ( grep -q "^$func$" || echo $func ) <<EOF | 7 | ( grep -q "^$func$" || echo $func ) <<EOF |
8 | __bss_start | 8 | __bss_start |
9 | _edata | 9 | _edata |
@@ -18,10 +18,12 @@ fd_bo_from_dmabuf | |||
18 | fd_bo_from_fbdev | 18 | fd_bo_from_fbdev |
19 | fd_bo_from_handle | 19 | fd_bo_from_handle |
20 | fd_bo_from_name | 20 | fd_bo_from_name |
21 | fd_bo_get_iova | ||
21 | fd_bo_get_name | 22 | fd_bo_get_name |
22 | fd_bo_handle | 23 | fd_bo_handle |
23 | fd_bo_map | 24 | fd_bo_map |
24 | fd_bo_new | 25 | fd_bo_new |
26 | fd_bo_put_iova | ||
25 | fd_bo_ref | 27 | fd_bo_ref |
26 | fd_bo_size | 28 | fd_bo_size |
27 | fd_device_del | 29 | fd_device_del |
@@ -33,6 +35,7 @@ fd_device_version | |||
33 | fd_pipe_del | 35 | fd_pipe_del |
34 | fd_pipe_get_param | 36 | fd_pipe_get_param |
35 | fd_pipe_new | 37 | fd_pipe_new |
38 | fd_pipe_new2 | ||
36 | fd_pipe_wait | 39 | fd_pipe_wait |
37 | fd_pipe_wait_timeout | 40 | fd_pipe_wait_timeout |
38 | fd_ringbuffer_cmd_count | 41 | fd_ringbuffer_cmd_count |
diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c index 996d6b95..34c285fb 100644 --- a/freedreno/freedreno_bo.c +++ b/freedreno/freedreno_bo.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include "freedreno_drmif.h" | 29 | #include "freedreno_drmif.h" |
34 | #include "freedreno_priv.h" | 30 | #include "freedreno_priv.h" |
35 | 31 | ||
@@ -102,6 +98,8 @@ fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) | |||
102 | bo->bo_reuse = TRUE; | 98 | bo->bo_reuse = TRUE; |
103 | pthread_mutex_unlock(&table_lock); | 99 | pthread_mutex_unlock(&table_lock); |
104 | 100 | ||
101 | VG_BO_ALLOC(bo); | ||
102 | |||
105 | return bo; | 103 | return bo; |
106 | } | 104 | } |
107 | 105 | ||
@@ -118,6 +116,8 @@ fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size) | |||
118 | 116 | ||
119 | bo = bo_from_handle(dev, size, handle); | 117 | bo = bo_from_handle(dev, size, handle); |
120 | 118 | ||
119 | VG_BO_ALLOC(bo); | ||
120 | |||
121 | out_unlock: | 121 | out_unlock: |
122 | pthread_mutex_unlock(&table_lock); | 122 | pthread_mutex_unlock(&table_lock); |
123 | 123 | ||
@@ -134,6 +134,7 @@ fd_bo_from_dmabuf(struct fd_device *dev, int fd) | |||
134 | pthread_mutex_lock(&table_lock); | 134 | pthread_mutex_lock(&table_lock); |
135 | ret = drmPrimeFDToHandle(dev->fd, fd, &handle); | 135 | ret = drmPrimeFDToHandle(dev->fd, fd, &handle); |
136 | if (ret) { | 136 | if (ret) { |
137 | pthread_mutex_unlock(&table_lock); | ||
137 | return NULL; | 138 | return NULL; |
138 | } | 139 | } |
139 | 140 | ||
@@ -147,6 +148,8 @@ fd_bo_from_dmabuf(struct fd_device *dev, int fd) | |||
147 | 148 | ||
148 | bo = bo_from_handle(dev, size, handle); | 149 | bo = bo_from_handle(dev, size, handle); |
149 | 150 | ||
151 | VG_BO_ALLOC(bo); | ||
152 | |||
150 | out_unlock: | 153 | out_unlock: |
151 | pthread_mutex_unlock(&table_lock); | 154 | pthread_mutex_unlock(&table_lock); |
152 | 155 | ||
@@ -177,8 +180,10 @@ struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name) | |||
177 | goto out_unlock; | 180 | goto out_unlock; |
178 | 181 | ||
179 | bo = bo_from_handle(dev, req.size, req.handle); | 182 | bo = bo_from_handle(dev, req.size, req.handle); |
180 | if (bo) | 183 | if (bo) { |
181 | set_name(bo, name); | 184 | set_name(bo, name); |
185 | VG_BO_ALLOC(bo); | ||
186 | } | ||
182 | 187 | ||
183 | out_unlock: | 188 | out_unlock: |
184 | pthread_mutex_unlock(&table_lock); | 189 | pthread_mutex_unlock(&table_lock); |
@@ -186,6 +191,16 @@ out_unlock: | |||
186 | return bo; | 191 | return bo; |
187 | } | 192 | } |
188 | 193 | ||
194 | uint64_t fd_bo_get_iova(struct fd_bo *bo) | ||
195 | { | ||
196 | return bo->funcs->iova(bo); | ||
197 | } | ||
198 | |||
199 | void fd_bo_put_iova(struct fd_bo *bo) | ||
200 | { | ||
201 | /* currently a no-op */ | ||
202 | } | ||
203 | |||
189 | struct fd_bo * fd_bo_ref(struct fd_bo *bo) | 204 | struct fd_bo * fd_bo_ref(struct fd_bo *bo) |
190 | { | 205 | { |
191 | atomic_inc(&bo->refcnt); | 206 | atomic_inc(&bo->refcnt); |
@@ -213,6 +228,8 @@ out: | |||
213 | /* Called under table_lock */ | 228 | /* Called under table_lock */ |
214 | drm_private void bo_del(struct fd_bo *bo) | 229 | drm_private void bo_del(struct fd_bo *bo) |
215 | { | 230 | { |
231 | VG_BO_FREE(bo); | ||
232 | |||
216 | if (bo->map) | 233 | if (bo->map) |
217 | drm_munmap(bo->map, bo->size); | 234 | drm_munmap(bo->map, bo->size); |
218 | 235 | ||
@@ -315,7 +332,7 @@ void fd_bo_cpu_fini(struct fd_bo *bo) | |||
315 | bo->funcs->cpu_fini(bo); | 332 | bo->funcs->cpu_fini(bo); |
316 | } | 333 | } |
317 | 334 | ||
318 | #ifndef HAVE_FREEDRENO_KGSL | 335 | #if !HAVE_FREEDRENO_KGSL |
319 | struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size) | 336 | struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size) |
320 | { | 337 | { |
321 | return NULL; | 338 | return NULL; |
diff --git a/freedreno/freedreno_bo_cache.c b/freedreno/freedreno_bo_cache.c index 7becb0d6..3b737159 100644 --- a/freedreno/freedreno_bo_cache.c +++ b/freedreno/freedreno_bo_cache.c | |||
@@ -26,14 +26,9 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include "freedreno_drmif.h" | 29 | #include "freedreno_drmif.h" |
34 | #include "freedreno_priv.h" | 30 | #include "freedreno_priv.h" |
35 | 31 | ||
36 | |||
37 | drm_private void bo_del(struct fd_bo *bo); | 32 | drm_private void bo_del(struct fd_bo *bo); |
38 | drm_private extern pthread_mutex_t table_lock; | 33 | drm_private extern pthread_mutex_t table_lock; |
39 | 34 | ||
@@ -102,6 +97,7 @@ fd_bo_cache_cleanup(struct fd_bo_cache *cache, time_t time) | |||
102 | if (time && ((time - bo->free_time) <= 1)) | 97 | if (time && ((time - bo->free_time) <= 1)) |
103 | break; | 98 | break; |
104 | 99 | ||
100 | VG_BO_OBTAIN(bo); | ||
105 | list_del(&bo->list); | 101 | list_del(&bo->list); |
106 | bo_del(bo); | 102 | bo_del(bo); |
107 | } | 103 | } |
@@ -177,6 +173,7 @@ retry: | |||
177 | *size = bucket->size; | 173 | *size = bucket->size; |
178 | bo = find_in_bucket(bucket, flags); | 174 | bo = find_in_bucket(bucket, flags); |
179 | if (bo) { | 175 | if (bo) { |
176 | VG_BO_OBTAIN(bo); | ||
180 | if (bo->funcs->madvise(bo, TRUE) <= 0) { | 177 | if (bo->funcs->madvise(bo, TRUE) <= 0) { |
181 | /* we've lost the backing pages, delete and try again: */ | 178 | /* we've lost the backing pages, delete and try again: */ |
182 | pthread_mutex_lock(&table_lock); | 179 | pthread_mutex_lock(&table_lock); |
@@ -207,6 +204,7 @@ fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo) | |||
207 | clock_gettime(CLOCK_MONOTONIC, &time); | 204 | clock_gettime(CLOCK_MONOTONIC, &time); |
208 | 205 | ||
209 | bo->free_time = time.tv_sec; | 206 | bo->free_time = time.tv_sec; |
207 | VG_BO_RELEASE(bo); | ||
210 | list_addtail(&bo->list, &bucket->list); | 208 | list_addtail(&bo->list, &bucket->list); |
211 | fd_bo_cache_cleanup(cache, time.tv_sec); | 209 | fd_bo_cache_cleanup(cache, time.tv_sec); |
212 | 210 | ||
diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c index fcbf1402..0b42561a 100644 --- a/freedreno/freedreno_device.c +++ b/freedreno/freedreno_device.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include <sys/types.h> | 29 | #include <sys/types.h> |
34 | #include <sys/stat.h> | 30 | #include <sys/stat.h> |
35 | #include <unistd.h> | 31 | #include <unistd.h> |
@@ -65,7 +61,7 @@ struct fd_device * fd_device_new(int fd) | |||
65 | 61 | ||
66 | dev = msm_device_new(fd); | 62 | dev = msm_device_new(fd); |
67 | dev->version = version->version_minor; | 63 | dev->version = version->version_minor; |
68 | #ifdef HAVE_FREEDRENO_KGSL | 64 | #if HAVE_FREEDRENO_KGSL |
69 | } else if (!strcmp(version->name, "kgsl")) { | 65 | } else if (!strcmp(version->name, "kgsl")) { |
70 | DEBUG_MSG("kgsl DRM device"); | 66 | DEBUG_MSG("kgsl DRM device"); |
71 | dev = kgsl_device_new(fd); | 67 | dev = kgsl_device_new(fd); |
@@ -112,12 +108,13 @@ struct fd_device * fd_device_ref(struct fd_device *dev) | |||
112 | 108 | ||
113 | static void fd_device_del_impl(struct fd_device *dev) | 109 | static void fd_device_del_impl(struct fd_device *dev) |
114 | { | 110 | { |
111 | int close_fd = dev->closefd ? dev->fd : -1; | ||
115 | fd_bo_cache_cleanup(&dev->bo_cache, 0); | 112 | fd_bo_cache_cleanup(&dev->bo_cache, 0); |
116 | drmHashDestroy(dev->handle_table); | 113 | drmHashDestroy(dev->handle_table); |
117 | drmHashDestroy(dev->name_table); | 114 | drmHashDestroy(dev->name_table); |
118 | if (dev->closefd) | ||
119 | close(dev->fd); | ||
120 | dev->funcs->destroy(dev); | 115 | dev->funcs->destroy(dev); |
116 | if (close_fd >= 0) | ||
117 | close(close_fd); | ||
121 | } | 118 | } |
122 | 119 | ||
123 | drm_private void fd_device_del_locked(struct fd_device *dev) | 120 | drm_private void fd_device_del_locked(struct fd_device *dev) |
diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h index 7a8073ff..2711518b 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,8 @@ 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 */ | ||
98 | FD_VERSION_BO_IOVA = 3, /* supports fd_bo_get/put_iova() */ | ||
96 | }; | 99 | }; |
97 | enum fd_version fd_device_version(struct fd_device *dev); | 100 | enum fd_version fd_device_version(struct fd_device *dev); |
98 | 101 | ||
@@ -100,6 +103,7 @@ enum fd_version fd_device_version(struct fd_device *dev); | |||
100 | */ | 103 | */ |
101 | 104 | ||
102 | struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); | 105 | struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); |
106 | 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); | 107 | void fd_pipe_del(struct fd_pipe *pipe); |
104 | int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, | 108 | int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, |
105 | uint64_t *value); | 109 | uint64_t *value); |
@@ -120,6 +124,8 @@ struct fd_bo *fd_bo_from_handle(struct fd_device *dev, | |||
120 | uint32_t handle, uint32_t size); | 124 | uint32_t handle, uint32_t size); |
121 | struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name); | 125 | struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name); |
122 | struct fd_bo * fd_bo_from_dmabuf(struct fd_device *dev, int fd); | 126 | struct fd_bo * fd_bo_from_dmabuf(struct fd_device *dev, int fd); |
127 | uint64_t fd_bo_get_iova(struct fd_bo *bo); | ||
128 | void fd_bo_put_iova(struct fd_bo *bo); | ||
123 | struct fd_bo * fd_bo_ref(struct fd_bo *bo); | 129 | struct fd_bo * fd_bo_ref(struct fd_bo *bo); |
124 | void fd_bo_del(struct fd_bo *bo); | 130 | void fd_bo_del(struct fd_bo *bo); |
125 | int fd_bo_get_name(struct fd_bo *bo, uint32_t *name); | 131 | int fd_bo_get_name(struct fd_bo *bo, uint32_t *name); |
diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c index 3f8c8342..77b160e7 100644 --- a/freedreno/freedreno_pipe.c +++ b/freedreno/freedreno_pipe.c | |||
@@ -26,28 +26,33 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include "freedreno_drmif.h" | 29 | #include "freedreno_drmif.h" |
34 | #include "freedreno_priv.h" | 30 | #include "freedreno_priv.h" |
35 | 31 | ||
32 | /** | ||
33 | * priority of zero is highest priority, and higher numeric values are | ||
34 | * lower priorities | ||
35 | */ | ||
36 | struct fd_pipe * | 36 | struct fd_pipe * |
37 | fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) | 37 | fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio) |
38 | { | 38 | { |
39 | struct fd_pipe *pipe = NULL; | 39 | struct fd_pipe *pipe; |
40 | uint64_t val; | 40 | uint64_t val; |
41 | 41 | ||
42 | if (id > FD_PIPE_MAX) { | 42 | if (id > FD_PIPE_MAX) { |
43 | ERROR_MSG("invalid pipe id: %d", id); | 43 | ERROR_MSG("invalid pipe id: %d", id); |
44 | goto fail; | 44 | return NULL; |
45 | } | ||
46 | |||
47 | if ((prio != 1) && (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES)) { | ||
48 | ERROR_MSG("invalid priority!"); | ||
49 | return NULL; | ||
45 | } | 50 | } |
46 | 51 | ||
47 | pipe = dev->funcs->pipe_new(dev, id); | 52 | pipe = dev->funcs->pipe_new(dev, id, prio); |
48 | if (!pipe) { | 53 | if (!pipe) { |
49 | ERROR_MSG("allocation failed"); | 54 | ERROR_MSG("allocation failed"); |
50 | goto fail; | 55 | return NULL; |
51 | } | 56 | } |
52 | 57 | ||
53 | pipe->dev = dev; | 58 | pipe->dev = dev; |
@@ -57,10 +62,12 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) | |||
57 | pipe->gpu_id = val; | 62 | pipe->gpu_id = val; |
58 | 63 | ||
59 | return pipe; | 64 | return pipe; |
60 | fail: | 65 | } |
61 | if (pipe) | 66 | |
62 | fd_pipe_del(pipe); | 67 | struct fd_pipe * |
63 | return NULL; | 68 | fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) |
69 | { | ||
70 | return fd_pipe_new2(dev, id, 1); | ||
64 | } | 71 | } |
65 | 72 | ||
66 | void fd_pipe_del(struct fd_pipe *pipe) | 73 | void fd_pipe_del(struct fd_pipe *pipe) |
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h index 32170391..6c9e509f 100644 --- a/freedreno/freedreno_priv.h +++ b/freedreno/freedreno_priv.h | |||
@@ -29,10 +29,6 @@ | |||
29 | #ifndef FREEDRENO_PRIV_H_ | 29 | #ifndef FREEDRENO_PRIV_H_ |
30 | #define FREEDRENO_PRIV_H_ | 30 | #define FREEDRENO_PRIV_H_ |
31 | 31 | ||
32 | #ifdef HAVE_CONFIG_H | ||
33 | #include "config.h" | ||
34 | #endif | ||
35 | |||
36 | #include <stdlib.h> | 32 | #include <stdlib.h> |
37 | #include <errno.h> | 33 | #include <errno.h> |
38 | #include <string.h> | 34 | #include <string.h> |
@@ -49,6 +45,7 @@ | |||
49 | #include "xf86atomic.h" | 45 | #include "xf86atomic.h" |
50 | 46 | ||
51 | #include "util_double_list.h" | 47 | #include "util_double_list.h" |
48 | #include "util_math.h" | ||
52 | 49 | ||
53 | #include "freedreno_drmif.h" | 50 | #include "freedreno_drmif.h" |
54 | #include "freedreno_ringbuffer.h" | 51 | #include "freedreno_ringbuffer.h" |
@@ -66,7 +63,8 @@ struct fd_device_funcs { | |||
66 | uint32_t flags, uint32_t *handle); | 63 | uint32_t flags, uint32_t *handle); |
67 | struct fd_bo * (*bo_from_handle)(struct fd_device *dev, | 64 | struct fd_bo * (*bo_from_handle)(struct fd_device *dev, |
68 | uint32_t size, uint32_t handle); | 65 | uint32_t size, uint32_t handle); |
69 | struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id); | 66 | struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id, |
67 | unsigned prio); | ||
70 | void (*destroy)(struct fd_device *dev); | 68 | void (*destroy)(struct fd_device *dev); |
71 | }; | 69 | }; |
72 | 70 | ||
@@ -102,6 +100,9 @@ struct fd_device { | |||
102 | struct fd_bo_cache bo_cache; | 100 | struct fd_bo_cache bo_cache; |
103 | 101 | ||
104 | int closefd; /* call close(fd) upon destruction */ | 102 | int closefd; /* call close(fd) upon destruction */ |
103 | |||
104 | /* just for valgrind: */ | ||
105 | int bo_size; | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse); | 108 | drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse); |
@@ -152,6 +153,7 @@ struct fd_bo_funcs { | |||
152 | int (*cpu_prep)(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op); | 153 | int (*cpu_prep)(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op); |
153 | void (*cpu_fini)(struct fd_bo *bo); | 154 | void (*cpu_fini)(struct fd_bo *bo); |
154 | int (*madvise)(struct fd_bo *bo, int willneed); | 155 | int (*madvise)(struct fd_bo *bo, int willneed); |
156 | uint64_t (*iova)(struct fd_bo *bo); | ||
155 | void (*destroy)(struct fd_bo *bo); | 157 | void (*destroy)(struct fd_bo *bo); |
156 | }; | 158 | }; |
157 | 159 | ||
@@ -169,7 +171,6 @@ struct fd_bo { | |||
169 | time_t free_time; /* time when added to bucket-list */ | 171 | time_t free_time; /* time when added to bucket-list */ |
170 | }; | 172 | }; |
171 | 173 | ||
172 | #define ALIGN(v,a) (((v) + (a) - 1) & ~((a) - 1)) | ||
173 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) | 174 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) |
174 | 175 | ||
175 | #define enable_debug 0 /* TODO make dynamic */ | 176 | #define enable_debug 0 /* TODO make dynamic */ |
@@ -196,4 +197,57 @@ offset_bytes(void *end, void *start) | |||
196 | return ((char *)end) - ((char *)start); | 197 | return ((char *)end) - ((char *)start); |
197 | } | 198 | } |
198 | 199 | ||
200 | #if HAVE_VALGRIND | ||
201 | # include <memcheck.h> | ||
202 | |||
203 | /* | ||
204 | * For tracking the backing memory (if valgrind enabled, we force a mmap | ||
205 | * for the purposes of tracking) | ||
206 | */ | ||
207 | static inline void VG_BO_ALLOC(struct fd_bo *bo) | ||
208 | { | ||
209 | if (bo && RUNNING_ON_VALGRIND) { | ||
210 | VALGRIND_MALLOCLIKE_BLOCK(fd_bo_map(bo), bo->size, 0, 1); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | static inline void VG_BO_FREE(struct fd_bo *bo) | ||
215 | { | ||
216 | VALGRIND_FREELIKE_BLOCK(bo->map, 0); | ||
217 | } | ||
218 | |||
219 | /* | ||
220 | * For tracking bo structs that are in the buffer-cache, so that valgrind | ||
221 | * doesn't attribute ownership to the first one to allocate the recycled | ||
222 | * bo. | ||
223 | * | ||
224 | * Note that the list_head in fd_bo is used to track the buffers in cache | ||
225 | * so disable error reporting on the range while they are in cache so | ||
226 | * valgrind doesn't squawk about list traversal. | ||
227 | * | ||
228 | */ | ||
229 | static inline void VG_BO_RELEASE(struct fd_bo *bo) | ||
230 | { | ||
231 | if (RUNNING_ON_VALGRIND) { | ||
232 | VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size); | ||
233 | VALGRIND_MAKE_MEM_NOACCESS(bo, bo->dev->bo_size); | ||
234 | VALGRIND_FREELIKE_BLOCK(bo->map, 0); | ||
235 | } | ||
236 | } | ||
237 | static inline void VG_BO_OBTAIN(struct fd_bo *bo) | ||
238 | { | ||
239 | if (RUNNING_ON_VALGRIND) { | ||
240 | VALGRIND_MAKE_MEM_DEFINED(bo, bo->dev->bo_size); | ||
241 | VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size); | ||
242 | VALGRIND_MALLOCLIKE_BLOCK(bo->map, bo->size, 0, 1); | ||
243 | } | ||
244 | } | ||
245 | #else | ||
246 | static inline void VG_BO_ALLOC(struct fd_bo *bo) {} | ||
247 | static inline void VG_BO_FREE(struct fd_bo *bo) {} | ||
248 | static inline void VG_BO_RELEASE(struct fd_bo *bo) {} | ||
249 | static inline void VG_BO_OBTAIN(struct fd_bo *bo) {} | ||
250 | #endif | ||
251 | |||
252 | |||
199 | #endif /* FREEDRENO_PRIV_H_ */ | 253 | #endif /* FREEDRENO_PRIV_H_ */ |
diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c index 7310f1fd..3834b51b 100644 --- a/freedreno/freedreno_ringbuffer.c +++ b/freedreno/freedreno_ringbuffer.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include <assert.h> | 29 | #include <assert.h> |
34 | 30 | ||
35 | #include "freedreno_drmif.h" | 31 | #include "freedreno_drmif.h" |
diff --git a/freedreno/kgsl/kgsl_bo.c b/freedreno/kgsl/kgsl_bo.c index ab3485e3..c6d2d499 100644 --- a/freedreno/kgsl/kgsl_bo.c +++ b/freedreno/kgsl/kgsl_bo.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include "kgsl_priv.h" | 29 | #include "kgsl_priv.h" |
34 | 30 | ||
35 | #include <linux/fb.h> | 31 | #include <linux/fb.h> |
diff --git a/freedreno/kgsl/kgsl_device.c b/freedreno/kgsl/kgsl_device.c index 175e8378..914f3412 100644 --- a/freedreno/kgsl/kgsl_device.c +++ b/freedreno/kgsl/kgsl_device.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include <sys/types.h> | 29 | #include <sys/types.h> |
34 | #include <sys/stat.h> | 30 | #include <sys/stat.h> |
35 | #include <unistd.h> | 31 | #include <unistd.h> |
@@ -61,5 +57,7 @@ drm_private struct fd_device * kgsl_device_new(int fd) | |||
61 | dev = &kgsl_dev->base; | 57 | dev = &kgsl_dev->base; |
62 | dev->funcs = &funcs; | 58 | dev->funcs = &funcs; |
63 | 59 | ||
60 | dev->bo_size = sizeof(struct kgsl_bo); | ||
61 | |||
64 | return dev; | 62 | return dev; |
65 | } | 63 | } |
diff --git a/freedreno/kgsl/kgsl_pipe.c b/freedreno/kgsl/kgsl_pipe.c index 8a39eb49..0a8b6586 100644 --- a/freedreno/kgsl/kgsl_pipe.c +++ b/freedreno/kgsl/kgsl_pipe.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include "kgsl_priv.h" | 29 | #include "kgsl_priv.h" |
34 | 30 | ||
35 | 31 | ||
@@ -52,6 +48,7 @@ static int kgsl_pipe_get_param(struct fd_pipe *pipe, | |||
52 | return 0; | 48 | return 0; |
53 | case FD_MAX_FREQ: | 49 | case FD_MAX_FREQ: |
54 | case FD_TIMESTAMP: | 50 | case FD_TIMESTAMP: |
51 | case FD_NR_RINGS: | ||
55 | /* unsupported on kgsl */ | 52 | /* unsupported on kgsl */ |
56 | return -1; | 53 | return -1; |
57 | default: | 54 | default: |
@@ -210,7 +207,7 @@ static int getprop(int fd, enum kgsl_property_type type, | |||
210 | 207 | ||
211 | 208 | ||
212 | drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, | 209 | drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, |
213 | enum fd_pipe_id id) | 210 | enum fd_pipe_id id, uint32_t prio) |
214 | { | 211 | { |
215 | static const char *paths[] = { | 212 | static const char *paths[] = { |
216 | [FD_PIPE_3D] = "/dev/kgsl-3d0", | 213 | [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/kgsl/kgsl_ringbuffer.c b/freedreno/kgsl/kgsl_ringbuffer.c index e4696b1b..a756deda 100644 --- a/freedreno/kgsl/kgsl_ringbuffer.c +++ b/freedreno/kgsl/kgsl_ringbuffer.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include <assert.h> | 29 | #include <assert.h> |
34 | 30 | ||
35 | #include "freedreno_ringbuffer.h" | 31 | #include "freedreno_ringbuffer.h" |
@@ -146,7 +142,7 @@ static int kgsl_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_star | |||
146 | ibdesc.gpuaddr = kgsl_ring->bo->gpuaddr; | 142 | ibdesc.gpuaddr = kgsl_ring->bo->gpuaddr; |
147 | ibdesc.hostptr = kgsl_ring->bo->hostptr; | 143 | ibdesc.hostptr = kgsl_ring->bo->hostptr; |
148 | ibdesc.sizedwords = 0x145; | 144 | ibdesc.sizedwords = 0x145; |
149 | req.timestamp = (uint32_t)kgsl_ring->bo->hostptr; | 145 | req.timestamp = (uintptr_t)kgsl_ring->bo->hostptr; |
150 | } | 146 | } |
151 | 147 | ||
152 | do { | 148 | do { |
diff --git a/freedreno/meson.build b/freedreno/meson.build new file mode 100644 index 00000000..015b7fb1 --- /dev/null +++ b/freedreno/meson.build | |||
@@ -0,0 +1,77 @@ | |||
1 | # Copyright © 2017-2018 Intel Corporation | ||
2 | |||
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy | ||
4 | # of this software and associated documentation files (the "Software"), to deal | ||
5 | # in the Software without restriction, including without limitation the rights | ||
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
7 | # copies of the Software, and to permit persons to whom the Software is | ||
8 | # furnished to do so, subject to the following conditions: | ||
9 | |||
10 | # The above copyright notice and this permission notice shall be included in | ||
11 | # all copies or substantial portions of the Software. | ||
12 | |||
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
19 | # SOFTWARE. | ||
20 | |||
21 | files_freedreno = files( | ||
22 | 'freedreno_device.c', | ||
23 | 'freedreno_pipe.c', | ||
24 | 'freedreno_ringbuffer.c', | ||
25 | 'freedreno_bo.c', | ||
26 | 'freedreno_bo_cache.c', | ||
27 | 'msm/msm_bo.c', | ||
28 | 'msm/msm_device.c', | ||
29 | 'msm/msm_pipe.c', | ||
30 | 'msm/msm_ringbuffer.c', | ||
31 | ) | ||
32 | |||
33 | if with_freedreno_kgsl | ||
34 | files_freedreno += files( | ||
35 | 'kgsl/kgsl_bo.c', | ||
36 | 'kgsl/kgsl_device.c', | ||
37 | 'kgsl/kgsl_pipe.c', | ||
38 | 'kgsl/kgsl_ringbuffer.c', | ||
39 | ) | ||
40 | endif | ||
41 | |||
42 | libdrm_freedreno = shared_library( | ||
43 | 'drm_freedreno', | ||
44 | [files_freedreno, config_file], | ||
45 | c_args : warn_c_args, | ||
46 | include_directories : [inc_root, inc_drm], | ||
47 | dependencies : [dep_valgrind, dep_pthread_stubs, dep_rt, dep_atomic_ops], | ||
48 | link_with : libdrm, | ||
49 | version : '1.0.0', | ||
50 | install : true, | ||
51 | ) | ||
52 | |||
53 | ext_libdrm_freedreno = declare_dependency( | ||
54 | link_with : [libdrm, libdrm_freedreno], | ||
55 | include_directories : [inc_drm, include_directories('.')], | ||
56 | ) | ||
57 | |||
58 | install_headers( | ||
59 | 'freedreno_drmif.h', 'freedreno_ringbuffer.h', | ||
60 | subdir : 'freedreno' | ||
61 | ) | ||
62 | |||
63 | pkg.generate( | ||
64 | name : 'libdrm_freedreno', | ||
65 | libraries : libdrm_freedreno, | ||
66 | subdirs : ['.', 'libdrm', 'freedreno'], | ||
67 | version : meson.project_version(), | ||
68 | requires_private : 'libdrm', | ||
69 | description : 'Userspace interface to freedreno kernel DRM services', | ||
70 | ) | ||
71 | |||
72 | test( | ||
73 | 'freedreno-symbol-check', | ||
74 | prog_bash, | ||
75 | env : env_test, | ||
76 | args : [files('freedreno-symbol-check'), libdrm_freedreno] | ||
77 | ) | ||
diff --git a/freedreno/msm/msm_bo.c b/freedreno/msm/msm_bo.c index 72471df6..8b3d0bcb 100644 --- a/freedreno/msm/msm_bo.c +++ b/freedreno/msm/msm_bo.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include "msm_priv.h" | 29 | #include "msm_priv.h" |
34 | 30 | ||
35 | static int bo_allocate(struct msm_bo *msm_bo) | 31 | static int bo_allocate(struct msm_bo *msm_bo) |
@@ -108,6 +104,18 @@ static int msm_bo_madvise(struct fd_bo *bo, int willneed) | |||
108 | return req.retained; | 104 | return req.retained; |
109 | } | 105 | } |
110 | 106 | ||
107 | static uint64_t msm_bo_iova(struct fd_bo *bo) | ||
108 | { | ||
109 | struct drm_msm_gem_info req = { | ||
110 | .handle = bo->handle, | ||
111 | .flags = MSM_INFO_IOVA, | ||
112 | }; | ||
113 | |||
114 | drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req)); | ||
115 | |||
116 | return req.offset; | ||
117 | } | ||
118 | |||
111 | static void msm_bo_destroy(struct fd_bo *bo) | 119 | static void msm_bo_destroy(struct fd_bo *bo) |
112 | { | 120 | { |
113 | struct msm_bo *msm_bo = to_msm_bo(bo); | 121 | struct msm_bo *msm_bo = to_msm_bo(bo); |
@@ -120,6 +128,7 @@ static const struct fd_bo_funcs funcs = { | |||
120 | .cpu_prep = msm_bo_cpu_prep, | 128 | .cpu_prep = msm_bo_cpu_prep, |
121 | .cpu_fini = msm_bo_cpu_fini, | 129 | .cpu_fini = msm_bo_cpu_fini, |
122 | .madvise = msm_bo_madvise, | 130 | .madvise = msm_bo_madvise, |
131 | .iova = msm_bo_iova, | ||
123 | .destroy = msm_bo_destroy, | 132 | .destroy = msm_bo_destroy, |
124 | }; | 133 | }; |
125 | 134 | ||
diff --git a/freedreno/msm/msm_device.c b/freedreno/msm/msm_device.c index 727baa44..7bb57677 100644 --- a/freedreno/msm/msm_device.c +++ b/freedreno/msm/msm_device.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include <sys/types.h> | 29 | #include <sys/types.h> |
34 | #include <sys/stat.h> | 30 | #include <sys/stat.h> |
35 | #include <unistd.h> | 31 | #include <unistd.h> |
@@ -64,5 +60,7 @@ drm_private struct fd_device * msm_device_new(int fd) | |||
64 | 60 | ||
65 | fd_bo_cache_init(&msm_dev->ring_cache, TRUE); | 61 | fd_bo_cache_init(&msm_dev->ring_cache, TRUE); |
66 | 62 | ||
63 | dev->bo_size = sizeof(struct msm_bo); | ||
64 | |||
67 | return dev; | 65 | return dev; |
68 | } | 66 | } |
diff --git a/freedreno/msm/msm_drm.h b/freedreno/msm/msm_drm.h index ed4c8d47..dac49e59 100644 --- a/freedreno/msm/msm_drm.h +++ b/freedreno/msm/msm_drm.h | |||
@@ -73,6 +73,8 @@ struct drm_msm_timespec { | |||
73 | #define MSM_PARAM_CHIP_ID 0x03 | 73 | #define MSM_PARAM_CHIP_ID 0x03 |
74 | #define MSM_PARAM_MAX_FREQ 0x04 | 74 | #define MSM_PARAM_MAX_FREQ 0x04 |
75 | #define MSM_PARAM_TIMESTAMP 0x05 | 75 | #define MSM_PARAM_TIMESTAMP 0x05 |
76 | #define MSM_PARAM_GMEM_BASE 0x06 | ||
77 | #define MSM_PARAM_NR_RINGS 0x07 | ||
76 | 78 | ||
77 | struct drm_msm_param { | 79 | struct drm_msm_param { |
78 | __u32 pipe; /* in, MSM_PIPE_x */ | 80 | __u32 pipe; /* in, MSM_PIPE_x */ |
@@ -104,10 +106,14 @@ struct drm_msm_gem_new { | |||
104 | __u32 handle; /* out */ | 106 | __u32 handle; /* out */ |
105 | }; | 107 | }; |
106 | 108 | ||
109 | #define MSM_INFO_IOVA 0x01 | ||
110 | |||
111 | #define MSM_INFO_FLAGS (MSM_INFO_IOVA) | ||
112 | |||
107 | struct drm_msm_gem_info { | 113 | struct drm_msm_gem_info { |
108 | __u32 handle; /* in */ | 114 | __u32 handle; /* in */ |
109 | __u32 pad; | 115 | __u32 flags; /* in - combination of MSM_INFO_* flags */ |
110 | __u64 offset; /* out, offset to pass to mmap() */ | 116 | __u64 offset; /* out, mmap() offset or iova */ |
111 | }; | 117 | }; |
112 | 118 | ||
113 | #define MSM_PREP_READ 0x01 | 119 | #define MSM_PREP_READ 0x01 |
@@ -167,7 +173,7 @@ struct drm_msm_gem_submit_cmd { | |||
167 | __u32 size; /* in, cmdstream size */ | 173 | __u32 size; /* in, cmdstream size */ |
168 | __u32 pad; | 174 | __u32 pad; |
169 | __u32 nr_relocs; /* in, number of submit_reloc's */ | 175 | __u32 nr_relocs; /* in, number of submit_reloc's */ |
170 | __u64 __user relocs; /* in, ptr to array of submit_reloc's */ | 176 | __u64 relocs; /* in, ptr to array of submit_reloc's */ |
171 | }; | 177 | }; |
172 | 178 | ||
173 | /* Each buffer referenced elsewhere in the cmdstream submit (ie. the | 179 | /* Each buffer referenced elsewhere in the cmdstream submit (ie. the |
@@ -211,9 +217,10 @@ struct drm_msm_gem_submit { | |||
211 | __u32 fence; /* out */ | 217 | __u32 fence; /* out */ |
212 | __u32 nr_bos; /* in, number of submit_bo's */ | 218 | __u32 nr_bos; /* in, number of submit_bo's */ |
213 | __u32 nr_cmds; /* in, number of submit_cmd's */ | 219 | __u32 nr_cmds; /* in, number of submit_cmd's */ |
214 | __u64 __user bos; /* in, ptr to array of submit_bo's */ | 220 | __u64 bos; /* in, ptr to array of submit_bo's */ |
215 | __u64 __user cmds; /* in, ptr to array of submit_cmd's */ | 221 | __u64 cmds; /* in, ptr to array of submit_cmd's */ |
216 | __s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */ | 222 | __s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */ |
223 | __u32 queueid; /* in, submitqueue id */ | ||
217 | }; | 224 | }; |
218 | 225 | ||
219 | /* The normal way to synchronize with the GPU is just to CPU_PREP on | 226 | /* The normal way to synchronize with the GPU is just to CPU_PREP on |
@@ -227,6 +234,7 @@ struct drm_msm_wait_fence { | |||
227 | __u32 fence; /* in */ | 234 | __u32 fence; /* in */ |
228 | __u32 pad; | 235 | __u32 pad; |
229 | struct drm_msm_timespec timeout; /* in */ | 236 | struct drm_msm_timespec timeout; /* in */ |
237 | __u32 queueid; /* in, submitqueue id */ | ||
230 | }; | 238 | }; |
231 | 239 | ||
232 | /* madvise provides a way to tell the kernel in case a buffers contents | 240 | /* madvise provides a way to tell the kernel in case a buffers contents |
@@ -250,6 +258,20 @@ struct drm_msm_gem_madvise { | |||
250 | __u32 retained; /* out, whether backing store still exists */ | 258 | __u32 retained; /* out, whether backing store still exists */ |
251 | }; | 259 | }; |
252 | 260 | ||
261 | /* | ||
262 | * Draw queues allow the user to set specific submission parameter. Command | ||
263 | * submissions specify a specific submitqueue to use. ID 0 is reserved for | ||
264 | * backwards compatibility as a "default" submitqueue | ||
265 | */ | ||
266 | |||
267 | #define MSM_SUBMITQUEUE_FLAGS (0) | ||
268 | |||
269 | struct drm_msm_submitqueue { | ||
270 | __u32 flags; /* in, MSM_SUBMITQUEUE_x */ | ||
271 | __u32 prio; /* in, Priority level */ | ||
272 | __u32 id; /* out, identifier */ | ||
273 | }; | ||
274 | |||
253 | #define DRM_MSM_GET_PARAM 0x00 | 275 | #define DRM_MSM_GET_PARAM 0x00 |
254 | /* placeholder: | 276 | /* placeholder: |
255 | #define DRM_MSM_SET_PARAM 0x01 | 277 | #define DRM_MSM_SET_PARAM 0x01 |
@@ -261,7 +283,11 @@ struct drm_msm_gem_madvise { | |||
261 | #define DRM_MSM_GEM_SUBMIT 0x06 | 283 | #define DRM_MSM_GEM_SUBMIT 0x06 |
262 | #define DRM_MSM_WAIT_FENCE 0x07 | 284 | #define DRM_MSM_WAIT_FENCE 0x07 |
263 | #define DRM_MSM_GEM_MADVISE 0x08 | 285 | #define DRM_MSM_GEM_MADVISE 0x08 |
264 | #define DRM_MSM_NUM_IOCTLS 0x09 | 286 | /* placeholder: |
287 | #define DRM_MSM_GEM_SVM_NEW 0x09 | ||
288 | */ | ||
289 | #define DRM_MSM_SUBMITQUEUE_NEW 0x0A | ||
290 | #define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B | ||
265 | 291 | ||
266 | #define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param) | 292 | #define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param) |
267 | #define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new) | 293 | #define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new) |
@@ -271,6 +297,8 @@ struct drm_msm_gem_madvise { | |||
271 | #define DRM_IOCTL_MSM_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_SUBMIT, struct drm_msm_gem_submit) | 297 | #define DRM_IOCTL_MSM_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_SUBMIT, struct drm_msm_gem_submit) |
272 | #define DRM_IOCTL_MSM_WAIT_FENCE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_WAIT_FENCE, struct drm_msm_wait_fence) | 298 | #define DRM_IOCTL_MSM_WAIT_FENCE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_WAIT_FENCE, struct drm_msm_wait_fence) |
273 | #define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise) | 299 | #define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise) |
300 | #define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue) | ||
301 | #define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32) | ||
274 | 302 | ||
275 | #if defined(__cplusplus) | 303 | #if defined(__cplusplus) |
276 | } | 304 | } |
diff --git a/freedreno/msm/msm_pipe.c b/freedreno/msm/msm_pipe.c index f872e245..f28778ef 100644 --- a/freedreno/msm/msm_pipe.c +++ b/freedreno/msm/msm_pipe.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include "msm_priv.h" | 29 | #include "msm_priv.h" |
34 | 30 | ||
35 | static int query_param(struct fd_pipe *pipe, uint32_t param, | 31 | static int query_param(struct fd_pipe *pipe, uint32_t param, |
@@ -71,6 +67,8 @@ static int msm_pipe_get_param(struct fd_pipe *pipe, | |||
71 | return query_param(pipe, MSM_PARAM_MAX_FREQ, value); | 67 | return query_param(pipe, MSM_PARAM_MAX_FREQ, value); |
72 | case FD_TIMESTAMP: | 68 | case FD_TIMESTAMP: |
73 | return query_param(pipe, MSM_PARAM_TIMESTAMP, value); | 69 | return query_param(pipe, MSM_PARAM_TIMESTAMP, value); |
70 | case FD_NR_RINGS: | ||
71 | return query_param(pipe, MSM_PARAM_NR_RINGS, value); | ||
74 | default: | 72 | default: |
75 | ERROR_MSG("invalid param id: %d", param); | 73 | ERROR_MSG("invalid param id: %d", param); |
76 | return -1; | 74 | return -1; |
@@ -83,6 +81,7 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp, | |||
83 | struct fd_device *dev = pipe->dev; | 81 | struct fd_device *dev = pipe->dev; |
84 | struct drm_msm_wait_fence req = { | 82 | struct drm_msm_wait_fence req = { |
85 | .fence = timestamp, | 83 | .fence = timestamp, |
84 | .queueid = to_msm_pipe(pipe)->queue_id, | ||
86 | }; | 85 | }; |
87 | int ret; | 86 | int ret; |
88 | 87 | ||
@@ -97,9 +96,48 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp, | |||
97 | return 0; | 96 | return 0; |
98 | } | 97 | } |
99 | 98 | ||
99 | static int open_submitqueue(struct fd_pipe *pipe, uint32_t prio) | ||
100 | { | ||
101 | struct drm_msm_submitqueue req = { | ||
102 | .flags = 0, | ||
103 | .prio = prio, | ||
104 | }; | ||
105 | uint64_t nr_rings = 1; | ||
106 | int ret; | ||
107 | |||
108 | if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES) { | ||
109 | to_msm_pipe(pipe)->queue_id = 0; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | msm_pipe_get_param(pipe, FD_NR_RINGS, &nr_rings); | ||
114 | |||
115 | req.prio = MIN2(req.prio, MAX2(nr_rings, 1) - 1); | ||
116 | |||
117 | ret = drmCommandWriteRead(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_NEW, | ||
118 | &req, sizeof(req)); | ||
119 | if (ret) { | ||
120 | ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno)); | ||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | to_msm_pipe(pipe)->queue_id = req.id; | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static void close_submitqueue(struct fd_pipe *pipe, uint32_t queue_id) | ||
129 | { | ||
130 | if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES) | ||
131 | return; | ||
132 | |||
133 | drmCommandWrite(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE, | ||
134 | &queue_id, sizeof(queue_id)); | ||
135 | } | ||
136 | |||
100 | static void msm_pipe_destroy(struct fd_pipe *pipe) | 137 | static void msm_pipe_destroy(struct fd_pipe *pipe) |
101 | { | 138 | { |
102 | struct msm_pipe *msm_pipe = to_msm_pipe(pipe); | 139 | struct msm_pipe *msm_pipe = to_msm_pipe(pipe); |
140 | close_submitqueue(pipe, msm_pipe->queue_id); | ||
103 | free(msm_pipe); | 141 | free(msm_pipe); |
104 | } | 142 | } |
105 | 143 | ||
@@ -122,7 +160,7 @@ static uint64_t get_param(struct fd_pipe *pipe, uint32_t param) | |||
122 | } | 160 | } |
123 | 161 | ||
124 | drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, | 162 | drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, |
125 | enum fd_pipe_id id) | 163 | enum fd_pipe_id id, uint32_t prio) |
126 | { | 164 | { |
127 | static const uint32_t pipe_id[] = { | 165 | static const uint32_t pipe_id[] = { |
128 | [FD_PIPE_3D] = MSM_PIPE_3D0, | 166 | [FD_PIPE_3D] = MSM_PIPE_3D0, |
@@ -157,6 +195,9 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, | |||
157 | INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id); | 195 | INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id); |
158 | INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem); | 196 | INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem); |
159 | 197 | ||
198 | if (open_submitqueue(pipe, prio)) | ||
199 | goto fail; | ||
200 | |||
160 | return pipe; | 201 | return pipe; |
161 | fail: | 202 | fail: |
162 | if (pipe) | 203 | 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 17194f4c..a87e1b9a 100644 --- a/freedreno/msm/msm_ringbuffer.c +++ b/freedreno/msm/msm_ringbuffer.c | |||
@@ -26,10 +26,6 @@ | |||
26 | * Rob Clark <robclark@freedesktop.org> | 26 | * Rob Clark <robclark@freedesktop.org> |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifdef HAVE_CONFIG_H | ||
30 | # include <config.h> | ||
31 | #endif | ||
32 | |||
33 | #include <assert.h> | 29 | #include <assert.h> |
34 | #include <inttypes.h> | 30 | #include <inttypes.h> |
35 | 31 | ||
@@ -401,6 +397,7 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start | |||
401 | struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); | 397 | struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); |
402 | struct drm_msm_gem_submit req = { | 398 | struct drm_msm_gem_submit req = { |
403 | .flags = to_msm_pipe(ring->pipe)->pipe, | 399 | .flags = to_msm_pipe(ring->pipe)->pipe, |
400 | .queueid = to_msm_pipe(ring->pipe)->queue_id, | ||
404 | }; | 401 | }; |
405 | uint32_t i; | 402 | uint32_t i; |
406 | int ret; | 403 | int ret; |
@@ -496,11 +493,16 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring, | |||
496 | if (ring->pipe->gpu_id >= 500) { | 493 | if (ring->pipe->gpu_id >= 500) { |
497 | struct drm_msm_gem_submit_reloc *reloc_hi; | 494 | struct drm_msm_gem_submit_reloc *reloc_hi; |
498 | 495 | ||
496 | /* NOTE: grab reloc_idx *before* APPEND() since that could | ||
497 | * realloc() meaning that 'reloc' ptr is no longer valid: | ||
498 | */ | ||
499 | uint32_t reloc_idx = reloc->reloc_idx; | ||
500 | |||
499 | idx = APPEND(cmd, relocs); | 501 | idx = APPEND(cmd, relocs); |
500 | 502 | ||
501 | reloc_hi = &cmd->relocs[idx]; | 503 | reloc_hi = &cmd->relocs[idx]; |
502 | 504 | ||
503 | reloc_hi->reloc_idx = reloc->reloc_idx; | 505 | reloc_hi->reloc_idx = reloc_idx; |
504 | reloc_hi->reloc_offset = r->offset; | 506 | reloc_hi->reloc_offset = r->offset; |
505 | reloc_hi->or = r->orhi; | 507 | reloc_hi->or = r->orhi; |
506 | reloc_hi->shift = r->shift - 32; | 508 | reloc_hi->shift = r->shift - 32; |
@@ -584,12 +586,12 @@ drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, | |||
584 | uint32_t size) | 586 | uint32_t size) |
585 | { | 587 | { |
586 | struct msm_ringbuffer *msm_ring; | 588 | struct msm_ringbuffer *msm_ring; |
587 | struct fd_ringbuffer *ring = NULL; | 589 | struct fd_ringbuffer *ring; |
588 | 590 | ||
589 | msm_ring = calloc(1, sizeof(*msm_ring)); | 591 | msm_ring = calloc(1, sizeof(*msm_ring)); |
590 | if (!msm_ring) { | 592 | if (!msm_ring) { |
591 | ERROR_MSG("allocation failed"); | 593 | ERROR_MSG("allocation failed"); |
592 | goto fail; | 594 | return NULL; |
593 | } | 595 | } |
594 | 596 | ||
595 | if (size == 0) { | 597 | if (size == 0) { |
@@ -609,8 +611,4 @@ drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, | |||
609 | ring_cmd_new(ring, size); | 611 | ring_cmd_new(ring, size); |
610 | 612 | ||
611 | return ring; | 613 | return ring; |
612 | fail: | ||
613 | if (ring) | ||
614 | fd_ringbuffer_del(ring); | ||
615 | return NULL; | ||
616 | } | 614 | } |