aboutsummaryrefslogtreecommitdiffstats
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/tegra.c
parentfb4177046de19730a784c3c16e4b73aab0ec6e41 (diff)
downloadexternal-libdrm-d6a4c2cbd11e357a9123f6d41f6d40d38e82e7f2.tar.gz
external-libdrm-d6a4c2cbd11e357a9123f6d41f6d40d38e82e7f2.tar.xz
external-libdrm-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/tegra.c')
-rw-r--r--tegra/tegra.c248
1 files changed, 248 insertions, 0 deletions
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}