Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / targets / xorg-vmwgfx / vmw_ioctl.c
1 /**********************************************************
2  * Copyright 2009 VMware, Inc.  All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  **********************************************************/
25
26 /**
27  * @file
28  * Contains the functions for creating dma buffers by calling
29  * the kernel via driver specific ioctls.
30  *
31  * @author Jakob Bornecrantz <jakob@vmware.com>
32  */
33
34 #ifndef HAVE_STDINT_H
35 #define HAVE_STDINT_H 1
36 #endif
37 #define _FILE_OFFSET_BITS 64
38
39 #include <errno.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include <sys/mman.h>
44 #include "xf86drm.h"
45 #include "../../winsys/svga/drm/vmwgfx_drm.h"
46
47 #include "vmw_driver.h"
48 #include "util/u_debug.h"
49
50 struct vmw_dma_buffer
51 {
52     void *data;
53     unsigned handle;
54     uint64_t map_handle;
55     unsigned map_count;
56     uint32_t size;
57 };
58
59 static int
60 vmw_ioctl_get_param(struct vmw_customizer *vmw, uint32_t param, uint64_t *out)
61 {
62     struct drm_vmw_getparam_arg gp_arg;
63     int ret;
64
65     memset(&gp_arg, 0, sizeof(gp_arg));
66     gp_arg.param = param;
67     ret = drmCommandWriteRead(vmw->fd, DRM_VMW_GET_PARAM,
68             &gp_arg, sizeof(gp_arg));
69
70     if (ret == 0) {
71         *out = gp_arg.value;
72     }
73
74     return ret;
75 }
76
77 int
78 vmw_ioctl_supports_streams(struct vmw_customizer *vmw)
79 {
80     uint64_t value;
81     int ret;
82
83     ret = vmw_ioctl_get_param(vmw, DRM_VMW_PARAM_NUM_STREAMS, &value);
84     if (ret)
85         return ret;
86
87     return value ? 0 : -ENOSYS;
88 }
89
90 int
91 vmw_ioctl_num_streams(struct vmw_customizer *vmw,
92                       uint32_t *ntot, uint32_t *nfree)
93 {
94     uint64_t v1, v2;
95     int ret;
96
97     ret = vmw_ioctl_get_param(vmw, DRM_VMW_PARAM_NUM_STREAMS, &v1);
98     if (ret)
99         return ret;
100
101     ret = vmw_ioctl_get_param(vmw, DRM_VMW_PARAM_NUM_FREE_STREAMS, &v2);
102     if (ret)
103         return ret;
104
105     *ntot = (uint32_t)v1;
106     *nfree = (uint32_t)v2;
107
108     return 0;
109 }
110
111 int
112 vmw_ioctl_claim_stream(struct vmw_customizer *vmw, uint32_t *out)
113 {
114     struct drm_vmw_stream_arg s_arg;
115     int ret;
116
117     ret = drmCommandRead(vmw->fd, DRM_VMW_CLAIM_STREAM,
118                          &s_arg, sizeof(s_arg));
119
120     if (ret)
121         return -1;
122
123     *out = s_arg.stream_id;
124     return 0;
125 }
126
127 int
128 vmw_ioctl_unref_stream(struct vmw_customizer *vmw, uint32_t stream_id)
129 {
130     struct drm_vmw_stream_arg s_arg;
131     int ret;
132
133     memset(&s_arg, 0, sizeof(s_arg));
134     s_arg.stream_id = stream_id;
135
136     ret = drmCommandRead(vmw->fd, DRM_VMW_CLAIM_STREAM,
137                          &s_arg, sizeof(s_arg));
138
139     return 0;
140 }
141
142 int
143 vmw_ioctl_cursor_bypass(struct vmw_customizer *vmw, int xhot, int yhot)
144 {
145     struct drm_vmw_cursor_bypass_arg arg;
146     int ret;
147
148     memset(&arg, 0, sizeof(arg));
149     arg.flags = DRM_VMW_CURSOR_BYPASS_ALL;
150     arg.xhot = xhot;
151     arg.yhot = yhot;
152
153     ret = drmCommandWrite(vmw->fd, DRM_VMW_CURSOR_BYPASS,
154                           &arg, sizeof(arg));
155
156     return ret;
157 }
158
159 struct vmw_dma_buffer *
160 vmw_ioctl_buffer_create(struct vmw_customizer *vmw, uint32_t size, unsigned *handle)
161 {
162     struct vmw_dma_buffer *buf;
163     union drm_vmw_alloc_dmabuf_arg arg;
164     struct drm_vmw_alloc_dmabuf_req *req = &arg.req;
165     struct drm_vmw_dmabuf_rep *rep = &arg.rep;
166     int ret;
167
168     buf = calloc(1, sizeof(*buf));
169     if (!buf)
170         goto err;
171
172     memset(&arg, 0, sizeof(arg));
173     req->size = size;
174     do {
175         ret = drmCommandWriteRead(vmw->fd, DRM_VMW_ALLOC_DMABUF, &arg, sizeof(arg));
176     } while (ret == -ERESTART);
177
178     if (ret) {
179         debug_printf("IOCTL failed %d: %s\n", ret, strerror(-ret));
180         goto err_free;
181     }
182
183
184     buf->data = NULL;
185     buf->handle = rep->handle;
186     buf->map_handle = rep->map_handle;
187     buf->map_count = 0;
188     buf->size = size;
189
190     *handle = rep->handle;
191
192     return buf;
193
194 err_free:
195     free(buf);
196 err:
197     return NULL;
198 }
199
200 void
201 vmw_ioctl_buffer_destroy(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
202
203     struct drm_vmw_unref_dmabuf_arg arg; 
204
205     if (buf->data) { 
206         munmap(buf->data, buf->size); 
207         buf->data = NULL; 
208     } 
209
210     memset(&arg, 0, sizeof(arg)); 
211     arg.handle = buf->handle; 
212     drmCommandWrite(vmw->fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg)); 
213
214     free(buf);
215
216
217 void *
218 vmw_ioctl_buffer_map(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
219 {
220     void *map;
221
222     if (buf->data == NULL) {
223         map = mmap(NULL, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED,
224                    vmw->fd, buf->map_handle);
225         if (map == MAP_FAILED) {
226             debug_printf("%s: Map failed.\n", __FUNCTION__);
227             return NULL;
228         }
229
230         buf->data = map;
231     }
232
233     ++buf->map_count;
234
235     return buf->data;
236 }
237
238 void
239 vmw_ioctl_buffer_unmap(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
240 {
241     --buf->map_count;
242 }
243
244 int
245 vmw_ioctl_update_layout(struct vmw_customizer *vmw, uint32_t num, struct vmw_rect *rects)
246 {
247     struct drm_vmw_update_layout_arg ul_arg;
248     int ret;
249
250     assert(sizeof(struct vmw_rect) == sizeof(struct drm_vmw_rect));
251
252     memset(&ul_arg, 0, sizeof(ul_arg));
253     ul_arg.num_outputs = num;
254     ul_arg.rects = (uint64_t)(uintptr_t)rects;
255
256     ret = drmCommandWriteRead(vmw->fd, DRM_VMW_UPDATE_LAYOUT,
257                               &ul_arg, sizeof(ul_arg));
258
259     return ret;
260 }