aboutsummaryrefslogtreecommitdiffstats
path: root/tegra
diff options
context:
space:
mode:
authorThierry Reding2012-12-01 03:30:38 -0600
committerThierry Reding2014-11-27 10:05:35 -0600
commitd6a4c2cbd11e357a9123f6d41f6d40d38e82e7f2 (patch)
tree22fb43f3d381c6d8dd953890a2b2ab533cee642d /tegra
parentfb4177046de19730a784c3c16e4b73aab0ec6e41 (diff)
downloadexternal-libgbm-d6a4c2cbd11e357a9123f6d41f6d40d38e82e7f2.tar.gz
external-libgbm-d6a4c2cbd11e357a9123f6d41f6d40d38e82e7f2.tar.xz
external-libgbm-d6a4c2cbd11e357a9123f6d41f6d40d38e82e7f2.zip
libdrm: Add NVIDIA Tegra support
Add the libdrm_tegra helper library to encapsulate Tegra-specific interfaces to the DRM. Furthermore, Tegra is added to the list of supported chips in the modetest and vbltest programs. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'tegra')
-rw-r--r--tegra/.gitignore1
-rw-r--r--tegra/Makefile.am23
-rw-r--r--tegra/libdrm_tegra.pc.in11
-rw-r--r--tegra/private.h51
-rw-r--r--tegra/tegra.c248
-rw-r--r--tegra/tegra.h47
6 files changed, 381 insertions, 0 deletions
diff --git a/tegra/.gitignore b/tegra/.gitignore
new file mode 100644
index 00000000..74cfe47a
--- /dev/null
+++ b/tegra/.gitignore
@@ -0,0 +1 @@
libdrm_tegra.pc
diff --git a/tegra/Makefile.am b/tegra/Makefile.am
new file mode 100644
index 00000000..a6474879
--- /dev/null
+++ b/tegra/Makefile.am
@@ -0,0 +1,23 @@
1AM_CPPFLAGS = \
2 -I$(top_srcdir) \
3 -I$(top_srcdir)/include/drm
4
5AM_CFLAGS = \
6 @PTHREADSTUBS_CFLAGS@ \
7 $(VISIBILITY_CFLAGS) \
8 $(WARN_CFLAGS)
9
10libdrm_tegra_ladir = $(libdir)
11libdrm_tegra_la_LTLIBRARIES = libdrm_tegra.la
12libdrm_tegra_la_LDFLAGS = -version-number 0:0:0 -no-undefined
13libdrm_tegra_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
14
15libdrm_tegra_la_SOURCES = \
16 private.h \
17 tegra.c
18
19libdrm_tegraincludedir = ${includedir}/libdrm
20libdrm_tegrainclude_HEADERS = tegra.h
21
22pkgconfigdir = @pkgconfigdir@
23pkgconfig_DATA = libdrm_tegra.pc
diff --git a/tegra/libdrm_tegra.pc.in b/tegra/libdrm_tegra.pc.in
new file mode 100644
index 00000000..2e06f49c
--- /dev/null
+++ b/tegra/libdrm_tegra.pc.in
@@ -0,0 +1,11 @@
1prefix=@prefix@
2exec_prefix=@exec_prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: libdrm_tegra
7Description: Userspace interface to Tegra kernel DRM services
8Version: @PACKAGE_VERSION@
9Libs: -L${libdir} -ldrm_tegra
10Cflags: -I${includedir} -I${includedir}/libdrm
11Requires.private: libdrm
diff --git a/tegra/private.h b/tegra/private.h
new file mode 100644
index 00000000..9b6bc939
--- /dev/null
+++ b/tegra/private.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright © 2012, 2013 Thierry Reding
3 * Copyright © 2013 Erik Faye-Lund
4 * Copyright © 2014 NVIDIA Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef __DRM_TEGRA_PRIVATE_H__
26#define __DRM_TEGRA_PRIVATE_H__ 1
27
28#include <stdbool.h>
29#include <stdint.h>
30
31#include <libdrm.h>
32#include <xf86atomic.h>
33
34#include "tegra.h"
35
36struct drm_tegra {
37 bool close;
38 int fd;
39};
40
41struct drm_tegra_bo {
42 struct drm_tegra *drm;
43 uint32_t handle;
44 uint32_t offset;
45 uint32_t flags;
46 uint32_t size;
47 atomic_t ref;
48 void *map;
49};
50
51#endif /* __DRM_TEGRA_PRIVATE_H__ */
diff --git a/tegra/tegra.c b/tegra/tegra.c
new file mode 100644
index 00000000..ec5bf76c
--- /dev/null
+++ b/tegra/tegra.c
@@ -0,0 +1,248 @@
1/*
2 * Copyright © 2012, 2013 Thierry Reding
3 * Copyright © 2013 Erik Faye-Lund
4 * Copyright © 2014 NVIDIA Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifdef HAVE_CONFIG_H
26# include "config.h"
27#endif
28
29#include <errno.h>
30#include <fcntl.h>
31#include <string.h>
32#include <unistd.h>
33
34#include <sys/mman.h>
35
36#include <xf86drm.h>
37
38#include <tegra_drm.h>
39
40#include "private.h"
41
42static void drm_tegra_bo_free(struct drm_tegra_bo *bo)
43{
44 struct drm_tegra *drm = bo->drm;
45 struct drm_gem_close args;
46
47 if (bo->map)
48 munmap(bo->map, bo->size);
49
50 memset(&args, 0, sizeof(args));
51 args.handle = bo->handle;
52
53 drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &args);
54
55 free(bo);
56}
57
58static int drm_tegra_wrap(struct drm_tegra **drmp, int fd, bool close)
59{
60 struct drm_tegra *drm;
61
62 if (fd < 0 || !drmp)
63 return -EINVAL;
64
65 drm = calloc(1, sizeof(*drm));
66 if (!drm)
67 return -ENOMEM;
68
69 drm->close = close;
70 drm->fd = fd;
71
72 *drmp = drm;
73
74 return 0;
75}
76
77drm_public
78int drm_tegra_new(struct drm_tegra **drmp, int fd)
79{
80 bool supported = false;
81 drmVersionPtr version;
82
83 version = drmGetVersion(fd);
84 if (!version)
85 return -ENOMEM;
86
87 if (!strncmp(version->name, "tegra", version->name_len))
88 supported = true;
89
90 drmFreeVersion(version);
91
92 if (!supported)
93 return -ENOTSUP;
94
95 return drm_tegra_wrap(drmp, fd, false);
96}
97
98drm_public
99void drm_tegra_close(struct drm_tegra *drm)
100{
101 if (!drm)
102 return;
103
104 if (drm->close)
105 close(drm->fd);
106
107 free(drm);
108}
109
110drm_public
111int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
112 uint32_t flags, uint32_t size)
113{
114 struct drm_tegra_gem_create args;
115 struct drm_tegra_bo *bo;
116 int err;
117
118 if (!drm || size == 0 || !bop)
119 return -EINVAL;
120
121 bo = calloc(1, sizeof(*bo));
122 if (!bo)
123 return -ENOMEM;
124
125 atomic_set(&bo->ref, 1);
126 bo->flags = flags;
127 bo->size = size;
128 bo->drm = drm;
129
130 memset(&args, 0, sizeof(args));
131 args.flags = flags;
132 args.size = size;
133
134 err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_CREATE, &args,
135 sizeof(args));
136 if (err < 0) {
137 err = -errno;
138 free(bo);
139 return err;
140 }
141
142 bo->handle = args.handle;
143
144 *bop = bo;
145
146 return 0;
147}
148
149drm_public
150int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm,
151 uint32_t handle, uint32_t flags, uint32_t size)
152{
153 struct drm_tegra_bo *bo;
154
155 if (!drm || !bop)
156 return -EINVAL;
157
158 bo = calloc(1, sizeof(*bo));
159 if (!bo)
160 return -ENOMEM;
161
162 atomic_set(&bo->ref, 1);
163 bo->handle = handle;
164 bo->flags = flags;
165 bo->size = size;
166 bo->drm = drm;
167
168 *bop = bo;
169
170 return 0;
171}
172
173drm_public
174struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo)
175{
176 if (bo)
177 atomic_inc(&bo->ref);
178
179 return bo;
180}
181
182drm_public
183void drm_tegra_bo_unref(struct drm_tegra_bo *bo)
184{
185 if (bo && atomic_dec_and_test(&bo->ref))
186 drm_tegra_bo_free(bo);
187}
188
189drm_public
190int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle)
191{
192 if (!bo || !handle)
193 return -EINVAL;
194
195 *handle = bo->handle;
196
197 return 0;
198}
199
200drm_public
201int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr)
202{
203 struct drm_tegra *drm = bo->drm;
204
205 if (!bo->map) {
206 struct drm_tegra_gem_mmap args;
207 int err;
208
209 memset(&args, 0, sizeof(args));
210 args.handle = bo->handle;
211
212 err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_MMAP, &args,
213 sizeof(args));
214 if (err < 0)
215 return -errno;
216
217 bo->offset = args.offset;
218
219 bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
220 drm->fd, bo->offset);
221 if (bo->map == MAP_FAILED) {
222 bo->map = NULL;
223 return -errno;
224 }
225 }
226
227 if (ptr)
228 *ptr = bo->map;
229
230 return 0;
231}
232
233drm_public
234int drm_tegra_bo_unmap(struct drm_tegra_bo *bo)
235{
236 if (!bo)
237 return -EINVAL;
238
239 if (!bo->map)
240 return 0;
241
242 if (munmap(bo->map, bo->size))
243 return -errno;
244
245 bo->map = NULL;
246
247 return 0;
248}
diff --git a/tegra/tegra.h b/tegra/tegra.h
new file mode 100644
index 00000000..ed29505d
--- /dev/null
+++ b/tegra/tegra.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright © 2012, 2013 Thierry Reding
3 * Copyright © 2013 Erik Faye-Lund
4 * Copyright © 2014 NVIDIA Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef __DRM_TEGRA_H__
26#define __DRM_TEGRA_H__ 1
27
28#include <stdint.h>
29#include <stdlib.h>
30
31struct drm_tegra_bo;
32struct drm_tegra;
33
34int drm_tegra_new(struct drm_tegra **drmp, int fd);
35void drm_tegra_close(struct drm_tegra *drm);
36
37int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
38 uint32_t flags, uint32_t size);
39int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm,
40 uint32_t handle, uint32_t flags, uint32_t size);
41struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo);
42void drm_tegra_bo_unref(struct drm_tegra_bo *bo);
43int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle);
44int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr);
45int drm_tegra_bo_unmap(struct drm_tegra_bo *bo);
46
47#endif /* __DRM_TEGRA_H__ */