aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'freedreno')
-rw-r--r--freedreno/Makefile.am1
-rwxr-xr-xfreedreno/freedreno-symbol-check5
-rw-r--r--freedreno/freedreno_bo.c29
-rw-r--r--freedreno/freedreno_bo_cache.c8
-rw-r--r--freedreno/freedreno_device.c11
-rw-r--r--freedreno/freedreno_drmif.h6
-rw-r--r--freedreno/freedreno_pipe.c33
-rw-r--r--freedreno/freedreno_priv.h66
-rw-r--r--freedreno/freedreno_ringbuffer.c4
-rw-r--r--freedreno/kgsl/kgsl_bo.c4
-rw-r--r--freedreno/kgsl/kgsl_device.c6
-rw-r--r--freedreno/kgsl/kgsl_pipe.c7
-rw-r--r--freedreno/kgsl/kgsl_priv.h2
-rw-r--r--freedreno/kgsl/kgsl_ringbuffer.c6
-rw-r--r--freedreno/meson.build77
-rw-r--r--freedreno/msm/msm_bo.c17
-rw-r--r--freedreno/msm/msm_device.c6
-rw-r--r--freedreno/msm/msm_drm.h40
-rw-r--r--freedreno/msm/msm_pipe.c51
-rw-r--r--freedreno/msm/msm_priv.h3
-rw-r--r--freedreno/msm/msm_ringbuffer.c20
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
10libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la 11libdrm_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
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_freedreno.so} | awk '{print $3}'| while read func; do 6FUNCS=$($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
18fd_bo_from_fbdev 18fd_bo_from_fbdev
19fd_bo_from_handle 19fd_bo_from_handle
20fd_bo_from_name 20fd_bo_from_name
21fd_bo_get_iova
21fd_bo_get_name 22fd_bo_get_name
22fd_bo_handle 23fd_bo_handle
23fd_bo_map 24fd_bo_map
24fd_bo_new 25fd_bo_new
26fd_bo_put_iova
25fd_bo_ref 27fd_bo_ref
26fd_bo_size 28fd_bo_size
27fd_device_del 29fd_device_del
@@ -33,6 +35,7 @@ fd_device_version
33fd_pipe_del 35fd_pipe_del
34fd_pipe_get_param 36fd_pipe_get_param
35fd_pipe_new 37fd_pipe_new
38fd_pipe_new2
36fd_pipe_wait 39fd_pipe_wait
37fd_pipe_wait_timeout 40fd_pipe_wait_timeout
38fd_ringbuffer_cmd_count 41fd_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
121out_unlock: 121out_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
150out_unlock: 153out_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
183out_unlock: 188out_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
194uint64_t fd_bo_get_iova(struct fd_bo *bo)
195{
196 return bo->funcs->iova(bo);
197}
198
199void fd_bo_put_iova(struct fd_bo *bo)
200{
201 /* currently a no-op */
202}
203
189struct fd_bo * fd_bo_ref(struct fd_bo *bo) 204struct 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 */
214drm_private void bo_del(struct fd_bo *bo) 229drm_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
319struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size) 336struct 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
37drm_private void bo_del(struct fd_bo *bo); 32drm_private void bo_del(struct fd_bo *bo);
38drm_private extern pthread_mutex_t table_lock; 33drm_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
113static void fd_device_del_impl(struct fd_device *dev) 109static 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
123drm_private void fd_device_del_locked(struct fd_device *dev) 120drm_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};
97enum fd_version fd_device_version(struct fd_device *dev); 100enum 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
102struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); 105struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id);
106struct 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); 107void fd_pipe_del(struct fd_pipe *pipe);
104int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, 108int 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);
121struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name); 125struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name);
122struct fd_bo * fd_bo_from_dmabuf(struct fd_device *dev, int fd); 126struct fd_bo * fd_bo_from_dmabuf(struct fd_device *dev, int fd);
127uint64_t fd_bo_get_iova(struct fd_bo *bo);
128void fd_bo_put_iova(struct fd_bo *bo);
123struct fd_bo * fd_bo_ref(struct fd_bo *bo); 129struct fd_bo * fd_bo_ref(struct fd_bo *bo);
124void fd_bo_del(struct fd_bo *bo); 130void fd_bo_del(struct fd_bo *bo);
125int fd_bo_get_name(struct fd_bo *bo, uint32_t *name); 131int 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 */
36struct fd_pipe * 36struct fd_pipe *
37fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) 37fd_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;
60fail: 65}
61 if (pipe) 66
62 fd_pipe_del(pipe); 67struct fd_pipe *
63 return NULL; 68fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
69{
70 return fd_pipe_new2(dev, id, 1);
64} 71}
65 72
66void fd_pipe_del(struct fd_pipe *pipe) 73void 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
107drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse); 108drm_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 */
207static 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
214static 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 */
229static 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}
237static 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
246static inline void VG_BO_ALLOC(struct fd_bo *bo) {}
247static inline void VG_BO_FREE(struct fd_bo *bo) {}
248static inline void VG_BO_RELEASE(struct fd_bo *bo) {}
249static 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
212drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, 209drm_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,
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/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
21files_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
33if 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 )
40endif
41
42libdrm_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
53ext_libdrm_freedreno = declare_dependency(
54 link_with : [libdrm, libdrm_freedreno],
55 include_directories : [inc_drm, include_directories('.')],
56)
57
58install_headers(
59 'freedreno_drmif.h', 'freedreno_ringbuffer.h',
60 subdir : 'freedreno'
61)
62
63pkg.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
72test(
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
35static int bo_allocate(struct msm_bo *msm_bo) 31static 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
107static 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
111static void msm_bo_destroy(struct fd_bo *bo) 119static 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
77struct drm_msm_param { 79struct 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
107struct drm_msm_gem_info { 113struct 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
269struct 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
35static int query_param(struct fd_pipe *pipe, uint32_t param, 31static 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
99static 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
128static 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
100static void msm_pipe_destroy(struct fd_pipe *pipe) 137static 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
124drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, 162drm_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;
161fail: 202fail:
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
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 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;
612fail:
613 if (ring)
614 fd_ringbuffer_del(ring);
615 return NULL;
616} 614}