aboutsummaryrefslogtreecommitdiffstats
path: root/omap
diff options
context:
space:
mode:
authorRob Clark2012-03-28 14:39:43 -0500
committerDaniel Vetter2012-03-28 16:00:14 -0500
commitef1b958cc831df3d33a366d1db2db2c88187229e (patch)
tree2b681262f81ffd3251f532b33561436006d3e5bc /omap
parent617213357e94299a5e9a3cb1342de55de949d156 (diff)
downloadexternal-libgbm-ef1b958cc831df3d33a366d1db2db2c88187229e.tar.gz
external-libgbm-ef1b958cc831df3d33a366d1db2db2c88187229e.tar.xz
external-libgbm-ef1b958cc831df3d33a366d1db2db2c88187229e.zip
omap: add omapdrm support
This adds libdrm_omap helper layer (as used by xf86-video-omap, omapdrmtest, etc). Signed-off-by: Rob Clark <rob@ti.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> [danvet: pushed for Rob, he doesn't yet have commit access.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'omap')
-rw-r--r--omap/Makefile.am22
-rw-r--r--omap/libdrm_omap.pc.in11
-rw-r--r--omap/omap_drm.c310
-rw-r--r--omap/omap_drm.h125
-rw-r--r--omap/omap_drmif.h61
5 files changed, 529 insertions, 0 deletions
diff --git a/omap/Makefile.am b/omap/Makefile.am
new file mode 100644
index 00000000..c77520b4
--- /dev/null
+++ b/omap/Makefile.am
@@ -0,0 +1,22 @@
1AM_CFLAGS = \
2 $(WARN_CFLAGS) \
3 -I$(top_srcdir) \
4 -I$(top_srcdir)/omap \
5 $(PTHREADSTUBS_CFLAGS) \
6 -I$(top_srcdir)/include/drm
7
8libdrm_omap_la_LTLIBRARIES = libdrm_omap.la
9libdrm_omap_ladir = $(libdir)
10libdrm_omap_la_LDFLAGS = -version-number 1:0:0 -no-undefined
11libdrm_omap_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
12
13libdrm_omap_la_SOURCES = omap_drm.c
14
15libdrm_omapcommonincludedir = ${includedir}/omap
16libdrm_omapcommoninclude_HEADERS = omap_drm.h
17
18libdrm_omapincludedir = ${includedir}/libdrm
19libdrm_omapinclude_HEADERS = omap_drmif.h
20
21pkgconfigdir = @pkgconfigdir@
22pkgconfig_DATA = libdrm_omap.pc
diff --git a/omap/libdrm_omap.pc.in b/omap/libdrm_omap.pc.in
new file mode 100644
index 00000000..024533bd
--- /dev/null
+++ b/omap/libdrm_omap.pc.in
@@ -0,0 +1,11 @@
1prefix=@prefix@
2exec_prefix=@exec_prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: libdrm_omap
7Description: Userspace interface to omap kernel DRM services
8Version: 0.6
9Libs: -L${libdir} -ldrm_omap
10Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/omap
11Requires.private: libdrm
diff --git a/omap/omap_drm.c b/omap/omap_drm.c
new file mode 100644
index 00000000..e6118065
--- /dev/null
+++ b/omap/omap_drm.c
@@ -0,0 +1,310 @@
1/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3/*
4 * Copyright (C) 2011 Texas Instruments, Inc
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 (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Authors:
26 * Rob Clark <rob@ti.com>
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <stdlib.h>
34#include <linux/stddef.h>
35#include <errno.h>
36#include <sys/mman.h>
37
38#include <xf86drm.h>
39
40#include "omap_drm.h"
41#include "omap_drmif.h"
42
43#define __round_mask(x, y) ((__typeof__(x))((y)-1))
44#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
45#define PAGE_SIZE 4096
46
47struct omap_device {
48 int fd;
49};
50
51/* a GEM buffer object allocated from the DRM device */
52struct omap_bo {
53 struct omap_device *dev;
54 void *map; /* userspace mmap'ing (if there is one) */
55 uint32_t size;
56 uint32_t handle;
57 uint32_t name; /* flink global handle (DRI2 name) */
58 uint64_t offset; /* offset to mmap() */
59};
60
61struct omap_device * omap_device_new(int fd)
62{
63 struct omap_device *dev = calloc(sizeof(*dev), 1);
64 if (!dev)
65 return NULL;
66 dev->fd = fd;
67 return dev;
68}
69
70void omap_device_del(struct omap_device *dev)
71{
72 free(dev);
73}
74
75int omap_get_param(struct omap_device *dev, uint64_t param, uint64_t *value)
76{
77 struct drm_omap_param req = {
78 .param = param,
79 };
80 int ret;
81
82 ret = drmCommandWriteRead(dev->fd, DRM_OMAP_GET_PARAM, &req, sizeof(req));
83 if (ret) {
84 return ret;
85 }
86
87 *value = req.value;
88
89 return 0;
90}
91
92int omap_set_param(struct omap_device *dev, uint64_t param, uint64_t value)
93{
94 struct drm_omap_param req = {
95 .param = param,
96 .value = value,
97 };
98 return drmCommandWrite(dev->fd, DRM_OMAP_SET_PARAM, &req, sizeof(req));
99}
100
101/* allocate a new buffer object */
102static struct omap_bo * omap_bo_new_impl(struct omap_device *dev,
103 union omap_gem_size size, uint32_t flags)
104{
105 struct omap_bo *bo;
106 struct drm_omap_gem_new req = {
107 .size = size,
108 .flags = flags,
109 };
110
111 if (size.bytes == 0) {
112 goto fail;
113 }
114
115 bo = calloc(sizeof(*bo), 1);
116 if (!bo) {
117 goto fail;
118 }
119
120 bo->dev = dev;
121
122 if (flags & OMAP_BO_TILED) {
123 bo->size = round_up(size.tiled.width, PAGE_SIZE) * size.tiled.height;
124 } else {
125 bo->size = size.bytes;
126 }
127
128 if (drmCommandWriteRead(dev->fd, DRM_OMAP_GEM_NEW, &req, sizeof(req))) {
129 goto fail;
130 }
131
132 bo->handle = req.handle;
133
134 return bo;
135
136fail:
137 free(bo);
138 return NULL;
139}
140
141
142/* allocate a new (un-tiled) buffer object */
143struct omap_bo * omap_bo_new(struct omap_device *dev,
144 uint32_t size, uint32_t flags)
145{
146 union omap_gem_size gsize = {
147 .bytes = size,
148 };
149 if (flags & OMAP_BO_TILED) {
150 return NULL;
151 }
152 return omap_bo_new_impl(dev, gsize, flags);
153}
154
155/* allocate a new buffer object */
156struct omap_bo * omap_bo_new_tiled(struct omap_device *dev,
157 uint32_t width, uint32_t height, uint32_t flags)
158{
159 union omap_gem_size gsize = {
160 .tiled = {
161 .width = width,
162 .height = height,
163 },
164 };
165 if (!(flags & OMAP_BO_TILED)) {
166 return NULL;
167 }
168 return omap_bo_new_impl(dev, gsize, flags);
169}
170
171/* get buffer info */
172static int get_buffer_info(struct omap_bo *bo)
173{
174 struct drm_omap_gem_info req = {
175 .handle = bo->handle,
176 };
177 int ret = drmCommandWriteRead(bo->dev->fd, DRM_OMAP_GEM_INFO,
178 &req, sizeof(req));
179 if (ret) {
180 return ret;
181 }
182
183 /* really all we need for now is mmap offset */
184 bo->offset = req.offset;
185 bo->size = req.size;
186
187 return 0;
188}
189
190/* import a buffer object from DRI2 name */
191struct omap_bo * omap_bo_from_name(struct omap_device *dev, uint32_t name)
192{
193 struct omap_bo *bo;
194 struct drm_gem_open req = {
195 .name = name,
196 };
197
198 bo = calloc(sizeof(*bo), 1);
199 if (!bo) {
200 goto fail;
201 }
202
203 if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
204 goto fail;
205 }
206
207 bo->dev = dev;
208 bo->name = name;
209 bo->handle = req.handle;
210
211 return bo;
212
213fail:
214 free(bo);
215 return NULL;
216}
217
218/* destroy a buffer object */
219void omap_bo_del(struct omap_bo *bo)
220{
221 if (!bo) {
222 return;
223 }
224
225 if (bo->map) {
226 munmap(bo->map, bo->size);
227 }
228
229 if (bo->handle) {
230 struct drm_gem_close req = {
231 .handle = bo->handle,
232 };
233
234 drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
235 }
236
237 free(bo);
238}
239
240/* get the global flink/DRI2 buffer name */
241int omap_bo_get_name(struct omap_bo *bo, uint32_t *name)
242{
243 if (!bo->name) {
244 struct drm_gem_flink req = {
245 .handle = bo->handle,
246 };
247 int ret;
248
249 ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
250 if (ret) {
251 return ret;
252 }
253
254 bo->name = req.name;
255 }
256
257 *name = bo->name;
258
259 return 0;
260}
261
262uint32_t omap_bo_handle(struct omap_bo *bo)
263{
264 return bo->handle;
265}
266
267uint32_t omap_bo_size(struct omap_bo *bo)
268{
269 if (!bo->size) {
270 get_buffer_info(bo);
271 }
272 return bo->size;
273}
274
275void * omap_bo_map(struct omap_bo *bo)
276{
277 if (!bo->map) {
278 if (!bo->offset) {
279 get_buffer_info(bo);
280 }
281
282 bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE,
283 MAP_SHARED, bo->dev->fd, bo->offset);
284 if (bo->map == MAP_FAILED) {
285 bo->map = NULL;
286 }
287 }
288 return bo->map;
289}
290
291int omap_bo_cpu_prep(struct omap_bo *bo, enum omap_gem_op op)
292{
293 struct drm_omap_gem_cpu_prep req = {
294 .handle = bo->handle,
295 .op = op,
296 };
297 return drmCommandWrite(bo->dev->fd,
298 DRM_OMAP_GEM_CPU_PREP, &req, sizeof(req));
299}
300
301int omap_bo_cpu_fini(struct omap_bo *bo, enum omap_gem_op op)
302{
303 struct drm_omap_gem_cpu_fini req = {
304 .handle = bo->handle,
305 .op = op,
306 .nregions = 0,
307 };
308 return drmCommandWrite(bo->dev->fd,
309 DRM_OMAP_GEM_CPU_FINI, &req, sizeof(req));
310}
diff --git a/omap/omap_drm.h b/omap/omap_drm.h
new file mode 100644
index 00000000..f277ceae
--- /dev/null
+++ b/omap/omap_drm.h
@@ -0,0 +1,125 @@
1/*
2 * include/drm/omap_drm.h
3 *
4 * Copyright (C) 2011 Texas Instruments
5 * Author: Rob Clark <rob@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef __OMAP_DRM_H__
21#define __OMAP_DRM_H__
22
23#include "drm.h"
24
25/* Please note that modifications to all structs defined here are
26 * subject to backwards-compatibility constraints.
27 */
28
29#define OMAP_PARAM_CHIPSET_ID 1 /* ie. 0x3430, 0x4430, etc */
30
31struct drm_omap_param {
32 uint64_t param; /* in */
33 uint64_t value; /* in (set_param), out (get_param) */
34};
35
36struct drm_omap_get_base {
37 char plugin_name[64]; /* in */
38 uint32_t ioctl_base; /* out */
39 uint32_t __pad;
40};
41
42#define OMAP_BO_SCANOUT 0x00000001 /* scanout capable (phys contiguous) */
43#define OMAP_BO_CACHE_MASK 0x00000006 /* cache type mask, see cache modes */
44#define OMAP_BO_TILED_MASK 0x00000f00 /* tiled mapping mask, see tiled modes */
45
46/* cache modes */
47#define OMAP_BO_CACHED 0x00000000 /* default */
48#define OMAP_BO_WC 0x00000002 /* write-combine */
49#define OMAP_BO_UNCACHED 0x00000004 /* strongly-ordered (uncached) */
50
51/* tiled modes */
52#define OMAP_BO_TILED_8 0x00000100
53#define OMAP_BO_TILED_16 0x00000200
54#define OMAP_BO_TILED_32 0x00000300
55#define OMAP_BO_TILED (OMAP_BO_TILED_8 | OMAP_BO_TILED_16 | OMAP_BO_TILED_32)
56
57union omap_gem_size {
58 uint32_t bytes; /* (for non-tiled formats) */
59 struct {
60 uint16_t width;
61 uint16_t height;
62 } tiled; /* (for tiled formats) */
63};
64
65struct drm_omap_gem_new {
66 union omap_gem_size size; /* in */
67 uint32_t flags; /* in */
68 uint32_t handle; /* out */
69 uint32_t __pad;
70};
71
72/* mask of operations: */
73enum omap_gem_op {
74 OMAP_GEM_READ = 0x01,
75 OMAP_GEM_WRITE = 0x02,
76};
77
78struct drm_omap_gem_cpu_prep {
79 uint32_t handle; /* buffer handle (in) */
80 uint32_t op; /* mask of omap_gem_op (in) */
81};
82
83struct drm_omap_gem_cpu_fini {
84 uint32_t handle; /* buffer handle (in) */
85 uint32_t op; /* mask of omap_gem_op (in) */
86 /* TODO maybe here we pass down info about what regions are touched
87 * by sw so we can be clever about cache ops? For now a placeholder,
88 * set to zero and we just do full buffer flush..
89 */
90 uint32_t nregions;
91 uint32_t __pad;
92};
93
94struct drm_omap_gem_info {
95 uint32_t handle; /* buffer handle (in) */
96 uint32_t pad;
97 uint64_t offset; /* mmap offset (out) */
98 /* note: in case of tiled buffers, the user virtual size can be
99 * different from the physical size (ie. how many pages are needed
100 * to back the object) which is returned in DRM_IOCTL_GEM_OPEN..
101 * This size here is the one that should be used if you want to
102 * mmap() the buffer:
103 */
104 uint32_t size; /* virtual size for mmap'ing (out) */
105 uint32_t __pad;
106};
107
108#define DRM_OMAP_GET_PARAM 0x00
109#define DRM_OMAP_SET_PARAM 0x01
110#define DRM_OMAP_GET_BASE 0x02
111#define DRM_OMAP_GEM_NEW 0x03
112#define DRM_OMAP_GEM_CPU_PREP 0x04
113#define DRM_OMAP_GEM_CPU_FINI 0x05
114#define DRM_OMAP_GEM_INFO 0x06
115#define DRM_OMAP_NUM_IOCTLS 0x07
116
117#define DRM_IOCTL_OMAP_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GET_PARAM, struct drm_omap_param)
118#define DRM_IOCTL_OMAP_SET_PARAM DRM_IOW (DRM_COMMAND_BASE + DRM_OMAP_SET_PARAM, struct drm_omap_param)
119#define DRM_IOCTL_OMAP_GET_BASE DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GET_BASE, struct drm_omap_get_base)
120#define DRM_IOCTL_OMAP_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GEM_NEW, struct drm_omap_gem_new)
121#define DRM_IOCTL_OMAP_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_OMAP_GEM_CPU_PREP, struct drm_omap_gem_cpu_prep)
122#define DRM_IOCTL_OMAP_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_OMAP_GEM_CPU_FINI, struct drm_omap_gem_cpu_fini)
123#define DRM_IOCTL_OMAP_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GEM_INFO, struct drm_omap_gem_info)
124
125#endif /* __OMAP_DRM_H__ */
diff --git a/omap/omap_drmif.h b/omap/omap_drmif.h
new file mode 100644
index 00000000..eb75a80a
--- /dev/null
+++ b/omap/omap_drmif.h
@@ -0,0 +1,61 @@
1/*
2 * Copyright (C) 2011 Texas Instruments, Inc
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 * Rob Clark <rob@ti.com>
25 */
26
27#ifndef OMAP_DRMIF_H_
28#define OMAP_DRMIF_H_
29
30#include <xf86drm.h>
31#include <stdint.h>
32#include <omap_drm.h>
33
34struct omap_bo;
35struct omap_device;
36
37/* device related functions:
38 */
39
40struct omap_device * omap_device_new(int fd);
41void omap_device_del(struct omap_device *dev);
42int omap_get_param(struct omap_device *dev, uint64_t param, uint64_t *value);
43int omap_set_param(struct omap_device *dev, uint64_t param, uint64_t value);
44
45/* buffer-object related functions:
46 */
47
48struct omap_bo * omap_bo_new(struct omap_device *dev,
49 uint32_t size, uint32_t flags);
50struct omap_bo * omap_bo_new_tiled(struct omap_device *dev,
51 uint32_t width, uint32_t height, uint32_t flags);
52struct omap_bo * omap_bo_from_name(struct omap_device *dev, uint32_t name);
53void omap_bo_del(struct omap_bo *bo);
54int omap_bo_get_name(struct omap_bo *bo, uint32_t *name);
55uint32_t omap_bo_handle(struct omap_bo *bo);
56uint32_t omap_bo_size(struct omap_bo *bo);
57void * omap_bo_map(struct omap_bo *bo);
58int omap_bo_cpu_prep(struct omap_bo *bo, enum omap_gem_op op);
59int omap_bo_cpu_fini(struct omap_bo *bo, enum omap_gem_op op);
60
61#endif /* OMAP_DRMIF_H_ */