initial commit
[ubuntu-omap:rsalvetis-xf86-video-omap.git] / src / omap_drm.c
1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3 /*
4  * Copyright © 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 /* This file is a staging area for OMAP DRM ioctl wrapper stuff that should
30  * eventually become part of libdrm.. for now, I'm still sorting the API out
31  * so it remains here until things stabilize.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include <stdlib.h>
39 #include <sys/mman.h>
40
41 #include "omap_drm.h"
42
43 struct omap_device {
44         int fd;
45 };
46
47 /* a GEM buffer object allocated from the DRM device */
48 struct omap_bo {
49         struct omap_device      *dev;
50         void            *map;           /* userspace mmap'ing (if there is one) */
51         uint32_t        size;
52         uint32_t        handle;
53         uint64_t        offset;         /* offset to mmap() */
54 };
55
56 struct omap_device * omap_device_new(int fd)
57 {
58         struct omap_device *dev = calloc(sizeof(*dev), 1);
59         dev->fd = fd;
60         return dev;
61 }
62
63 void omap_device_del(struct omap_device *dev)
64 {
65         free(dev);
66 }
67
68 int omap_get_param(struct omap_device *dev, uint64_t param, uint64_t *value)
69 {
70         struct drm_omap_param req = {
71                         .param = param,
72         };
73         int ret;
74
75         ret = drmCommandWriteRead(dev->fd, DRM_OMAP_GET_PARAM, &req, sizeof(req));
76         if (ret) {
77                 return ret;
78         }
79
80         *value = req.value;
81
82         return 0;
83 }
84
85 int omap_set_param(struct omap_device *dev, uint64_t param, uint64_t value)
86 {
87         struct drm_omap_param req = {
88                         .param = param,
89                         .value = value,
90         };
91         return drmCommandWrite(dev->fd, DRM_OMAP_GET_PARAM, &req, sizeof(req));
92 }
93
94 /* allocate a new (un-tiled) buffer object */
95 struct omap_bo * omap_bo_new(struct omap_device *dev,
96                 uint32_t size, uint32_t flags)
97 {
98         struct omap_bo *bo = calloc(sizeof(*bo), 1);
99         struct drm_omap_gem_new req = {
100                         .size = size,
101                         .flags = flags,
102         };
103
104         if (size == 0) {
105                 goto fail;
106         }
107
108         if (!bo) {
109                 goto fail;
110         }
111
112         bo->dev = dev;
113         bo->size = size;
114
115         if (drmCommandWriteRead(dev->fd, DRM_OMAP_GEM_NEW,
116                                   &req, sizeof(req))) {
117                 goto fail;
118         }
119
120         bo->handle = req.handle;
121         bo->offset = req.offset;
122
123         return bo;
124
125 fail:
126         free(bo);
127         return NULL;
128 }
129
130 /* destroy a buffer object */
131 void omap_bo_del(struct omap_bo *bo)
132 {
133         if (!bo) {
134                 return;
135         }
136
137         if (bo->map) {
138                 munmap(bo->map, bo->size);
139         }
140
141         if (bo->handle) {
142                 struct drm_gem_close req = {
143                                 .handle = bo->handle,
144                 };
145
146                 drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
147         }
148
149         free(bo);
150 }
151
152 uint32_t omap_bo_handle(struct omap_bo *bo)
153 {
154         return bo->handle;
155 }
156
157 uint32_t omap_bo_size(struct omap_bo *bo)
158 {
159         return bo->size;
160 }
161
162 void * omap_bo_map(struct omap_bo *bo)
163 {
164         if (!bo->map) {
165                 bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE,
166                                  MAP_SHARED, bo->dev->fd, bo->offset);
167                 if (bo->map == MAP_FAILED) {
168                         bo->map = NULL;
169                 }
170         }
171         return bo->map;
172 }