diff options
Diffstat (limited to 'libkms')
-rw-r--r-- | libkms/Makefile.am | 1 | ||||
-rw-r--r-- | libkms/api.c | 1 | ||||
-rw-r--r-- | libkms/intel.c | 256 | ||||
-rw-r--r-- | libkms/internal.h | 2 |
4 files changed, 260 insertions, 0 deletions
diff --git a/libkms/Makefile.am b/libkms/Makefile.am index 1ecad774..23f78e08 100644 --- a/libkms/Makefile.am +++ b/libkms/Makefile.am | |||
@@ -10,6 +10,7 @@ libkms_la_LIBADD = \ | |||
10 | 10 | ||
11 | libkms_la_SOURCES = \ | 11 | libkms_la_SOURCES = \ |
12 | linux.c \ | 12 | linux.c \ |
13 | intel.c \ | ||
13 | api.c | 14 | api.c |
14 | 15 | ||
15 | if HAVE_VMWGFX | 16 | if HAVE_VMWGFX |
diff --git a/libkms/api.c b/libkms/api.c index 6cec4b96..12dcd9a1 100644 --- a/libkms/api.c +++ b/libkms/api.c | |||
@@ -40,6 +40,7 @@ struct create_record | |||
40 | }; | 40 | }; |
41 | 41 | ||
42 | static struct create_record table[] = { | 42 | static struct create_record table[] = { |
43 | { 0x8086, 0x2a42, intel_create }, /* i965 */ | ||
43 | #ifdef HAVE_VMWGFX | 44 | #ifdef HAVE_VMWGFX |
44 | { 0x15ad, 0x0405, vmwgfx_create }, /* VMware vGPU */ | 45 | { 0x15ad, 0x0405, vmwgfx_create }, /* VMware vGPU */ |
45 | #endif | 46 | #endif |
diff --git a/libkms/intel.c b/libkms/intel.c new file mode 100644 index 00000000..6dd739d5 --- /dev/null +++ b/libkms/intel.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /************************************************************************** | ||
2 | * | ||
3 | * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA | ||
4 | * All Rights Reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the | ||
8 | * "Software"), to deal in the Software without restriction, including | ||
9 | * without limitation the rights to use, copy, modify, merge, publish, | ||
10 | * distribute, sub license, and/or sell copies of the Software, and to | ||
11 | * permit persons to whom the Software is furnished to do so, subject to | ||
12 | * the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice (including the | ||
15 | * next paragraph) shall be included in all copies or substantial portions | ||
16 | * of the Software. | ||
17 | * | ||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
21 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | ||
22 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
23 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
24 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
25 | * | ||
26 | **************************************************************************/ | ||
27 | |||
28 | |||
29 | #define HAVE_STDINT_H | ||
30 | #define _FILE_OFFSET_BITS 64 | ||
31 | |||
32 | #include <errno.h> | ||
33 | #include <stdio.h> | ||
34 | #include <stdlib.h> | ||
35 | #include <string.h> | ||
36 | #include "internal.h" | ||
37 | |||
38 | #include <sys/mman.h> | ||
39 | #include <sys/ioctl.h> | ||
40 | #include "xf86drm.h" | ||
41 | |||
42 | #include "i915_drm.h" | ||
43 | |||
44 | struct intel_bo | ||
45 | { | ||
46 | struct kms_bo base; | ||
47 | unsigned handle; | ||
48 | unsigned map_count; | ||
49 | int mapped; | ||
50 | }; | ||
51 | |||
52 | static int | ||
53 | intel_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) | ||
54 | { | ||
55 | switch (key) { | ||
56 | case KMS_MAX_SCANOUT_WIDTH: | ||
57 | *out = 4096; | ||
58 | break; | ||
59 | case KMS_MAX_SCANOUT_HEIGHT: | ||
60 | *out = 4096; | ||
61 | break; | ||
62 | case KMS_MIN_SCANOUT_WIDTH: | ||
63 | *out = 1; | ||
64 | break; | ||
65 | case KMS_MIN_SCANOUT_HEIGHT: | ||
66 | *out = 1; | ||
67 | break; | ||
68 | case KMS_MAX_CURSOR_WIDTH: | ||
69 | *out = 64; | ||
70 | break; | ||
71 | case KMS_MAX_CURSOR_HEIGHT: | ||
72 | *out = 64; | ||
73 | break; | ||
74 | case KMS_MIN_CURSOR_WIDTH: | ||
75 | *out = 64; | ||
76 | break; | ||
77 | case KMS_MIN_CURSOR_HEIGHT: | ||
78 | *out = 64; | ||
79 | break; | ||
80 | default: | ||
81 | return -EINVAL; | ||
82 | } | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static int | ||
87 | intel_destroy(struct kms_driver *kms) | ||
88 | { | ||
89 | free(kms); | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static int | ||
94 | intel_bo_create(struct kms_driver *kms, | ||
95 | const unsigned width, const unsigned height, | ||
96 | const enum kms_bo_type type, const unsigned *attr, | ||
97 | struct kms_bo **out) | ||
98 | { | ||
99 | struct drm_i915_gem_create arg; | ||
100 | unsigned size, pitch; | ||
101 | struct intel_bo *bo; | ||
102 | int i, ret; | ||
103 | |||
104 | for (i = 0; attr[i]; i += 2) { | ||
105 | switch (attr[i]) { | ||
106 | case KMS_WIDTH: | ||
107 | case KMS_HEIGHT: | ||
108 | case KMS_BO_TYPE: | ||
109 | break; | ||
110 | default: | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | bo = calloc(1, sizeof(*bo)); | ||
116 | if (!bo) | ||
117 | return -ENOMEM; | ||
118 | |||
119 | if (type == KMS_BO_TYPE_CURSOR) { | ||
120 | pitch = 64 * 4; | ||
121 | size = 64 * 64 * 4; | ||
122 | } else if (type == KMS_BO_TYPE_SCANOUT) { | ||
123 | pitch = width * 4; | ||
124 | pitch = (pitch + 512 - 1) & ~(512 - 1); | ||
125 | size = pitch * ((height + 4 - 1) & ~(4 - 1)); | ||
126 | } else { | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | |||
130 | memset(&arg, 0, sizeof(arg)); | ||
131 | arg.size = size; | ||
132 | |||
133 | ret = drmCommandWriteRead(kms->fd, DRM_I915_GEM_CREATE, &arg, sizeof(arg)); | ||
134 | if (ret) | ||
135 | goto err_free; | ||
136 | |||
137 | bo->base.kms = kms; | ||
138 | bo->base.handle = arg.handle; | ||
139 | bo->base.size = size; | ||
140 | bo->base.pitch = pitch; | ||
141 | |||
142 | *out = &bo->base; | ||
143 | if (type == KMS_BO_TYPE_SCANOUT && pitch > 512) { | ||
144 | struct drm_i915_gem_set_tiling tile; | ||
145 | |||
146 | memset(&tile, 0, sizeof(tile)); | ||
147 | tile.handle = bo->base.handle; | ||
148 | tile.tiling_mode = I915_TILING_X; | ||
149 | tile.stride = bo->base.pitch; | ||
150 | |||
151 | ret = drmCommandWriteRead(kms->fd, DRM_I915_GEM_SET_TILING, &tile, sizeof(tile)); | ||
152 | if (ret != 0) | ||
153 | goto err_destroy; | ||
154 | } | ||
155 | |||
156 | return 0; | ||
157 | |||
158 | err_destroy: | ||
159 | kms_bo_destroy(out); | ||
160 | err_free: | ||
161 | free(bo); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | static int | ||
166 | intel_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) | ||
167 | { | ||
168 | switch (key) { | ||
169 | default: | ||
170 | return -EINVAL; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | static int | ||
175 | intel_bo_map(struct kms_bo *_bo, void **out) | ||
176 | { | ||
177 | struct intel_bo *bo = (struct intel_bo *)_bo; | ||
178 | struct drm_i915_gem_mmap_gtt arg; | ||
179 | void *map = NULL; | ||
180 | int ret; | ||
181 | |||
182 | if (bo->base.ptr) { | ||
183 | bo->map_count++; | ||
184 | *out = bo->base.ptr; | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | memset(&arg, 0, sizeof(arg)); | ||
189 | arg.handle = bo->base.handle; | ||
190 | |||
191 | ret = drmCommandWriteRead(bo->base.kms->fd, DRM_I915_GEM_MMAP_GTT, &arg, sizeof(arg)); | ||
192 | if (ret) | ||
193 | return ret; | ||
194 | |||
195 | map = mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset); | ||
196 | if (map == MAP_FAILED) | ||
197 | return -errno; | ||
198 | |||
199 | bo->base.ptr = map; | ||
200 | bo->map_count++; | ||
201 | *out = bo->base.ptr; | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static int | ||
207 | intel_bo_unmap(struct kms_bo *_bo) | ||
208 | { | ||
209 | struct intel_bo *bo = (struct intel_bo *)_bo; | ||
210 | bo->map_count--; | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static int | ||
215 | intel_bo_destroy(struct kms_bo *_bo) | ||
216 | { | ||
217 | struct intel_bo *bo = (struct intel_bo *)_bo; | ||
218 | struct drm_gem_close arg; | ||
219 | int ret; | ||
220 | |||
221 | if (bo->base.ptr) | ||
222 | munmap(bo->base.ptr, bo->base.size); | ||
223 | |||
224 | memset(&arg, 0, sizeof(arg)); | ||
225 | arg.handle = bo->base.handle; | ||
226 | |||
227 | ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg); | ||
228 | if (ret) | ||
229 | return -errno; | ||
230 | |||
231 | free(bo); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | int | ||
236 | intel_create(int fd, struct kms_driver **out) | ||
237 | { | ||
238 | struct kms_driver *kms; | ||
239 | |||
240 | kms = calloc(1, sizeof(*kms)); | ||
241 | if (!kms) | ||
242 | return -ENOMEM; | ||
243 | |||
244 | kms->fd = fd; | ||
245 | |||
246 | kms->bo_create = intel_bo_create; | ||
247 | kms->bo_map = intel_bo_map; | ||
248 | kms->bo_unmap = intel_bo_unmap; | ||
249 | kms->bo_get_prop = intel_bo_get_prop; | ||
250 | kms->bo_destroy = intel_bo_destroy; | ||
251 | kms->get_prop = intel_get_prop; | ||
252 | kms->destroy = intel_destroy; | ||
253 | *out = kms; | ||
254 | |||
255 | return 0; | ||
256 | } | ||
diff --git a/libkms/internal.h b/libkms/internal.h index cdc27053..a441266b 100644 --- a/libkms/internal.h +++ b/libkms/internal.h | |||
@@ -66,4 +66,6 @@ int linux_get_pciid_from_fd(int fd, unsigned *vendor_id, unsigned *chip_id); | |||
66 | 66 | ||
67 | int vmwgfx_create(int fd, struct kms_driver **out); | 67 | int vmwgfx_create(int fd, struct kms_driver **out); |
68 | 68 | ||
69 | int intel_create(int fd, struct kms_driver **out); | ||
70 | |||
69 | #endif | 71 | #endif |