Merge remote-tracking branch 'origin/master' into pipe-video
[mesa.git] / src / gallium / winsys / r600 / drm / r600_drm.c
1 /*
2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Jerome Glisse
25 * Corbin Simpson <MostAwesomeDude@gmail.com>
26 * Joakim Sindholt <opensource@zhasha.com>
27 */
28 #include <stdio.h>
29 #include <errno.h>
30 #include <sys/ioctl.h>
31 #include "util/u_inlines.h"
32 #include "util/u_debug.h"
33 #include "util/u_hash_table.h"
34 #include <pipebuffer/pb_bufmgr.h>
35 #include "r600.h"
36 #include "r600_priv.h"
37 #include "r600_drm_public.h"
38 #include "xf86drm.h"
39 #include "radeon_drm.h"
40
41 #ifndef RADEON_INFO_TILING_CONFIG
42 #define RADEON_INFO_TILING_CONFIG 0x6
43 #endif
44
45 #ifndef RADEON_INFO_CLOCK_CRYSTAL_FREQ
46 #define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x9
47 #endif
48
49 #ifndef RADEON_INFO_NUM_BACKENDS
50 #define RADEON_INFO_NUM_BACKENDS 0xa
51 #endif
52
53 enum radeon_family r600_get_family(struct radeon *r600)
54 {
55 return r600->family;
56 }
57
58 enum chip_class r600_get_family_class(struct radeon *radeon)
59 {
60 return radeon->chip_class;
61 }
62
63 struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon)
64 {
65 return &radeon->tiling_info;
66 }
67
68 unsigned r600_get_clock_crystal_freq(struct radeon *radeon)
69 {
70 return radeon->clock_crystal_freq;
71 }
72
73 unsigned r600_get_num_backends(struct radeon *radeon)
74 {
75 return radeon->num_backends;
76 }
77
78 unsigned r600_get_minor_version(struct radeon *radeon)
79 {
80 return radeon->minor_version;
81 }
82
83
84 static int radeon_get_device(struct radeon *radeon)
85 {
86 struct drm_radeon_info info = {};
87 int r;
88
89 radeon->device = 0;
90 info.request = RADEON_INFO_DEVICE_ID;
91 info.value = (uintptr_t)&radeon->device;
92 r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
93 sizeof(struct drm_radeon_info));
94 return r;
95 }
96
97 static int r600_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
98 {
99 switch ((tiling_config & 0xe) >> 1) {
100 case 0:
101 radeon->tiling_info.num_channels = 1;
102 break;
103 case 1:
104 radeon->tiling_info.num_channels = 2;
105 break;
106 case 2:
107 radeon->tiling_info.num_channels = 4;
108 break;
109 case 3:
110 radeon->tiling_info.num_channels = 8;
111 break;
112 default:
113 return -EINVAL;
114 }
115
116 switch ((tiling_config & 0x30) >> 4) {
117 case 0:
118 radeon->tiling_info.num_banks = 4;
119 break;
120 case 1:
121 radeon->tiling_info.num_banks = 8;
122 break;
123 default:
124 return -EINVAL;
125
126 }
127 switch ((tiling_config & 0xc0) >> 6) {
128 case 0:
129 radeon->tiling_info.group_bytes = 256;
130 break;
131 case 1:
132 radeon->tiling_info.group_bytes = 512;
133 break;
134 default:
135 return -EINVAL;
136 }
137 return 0;
138 }
139
140 static int eg_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
141 {
142 switch (tiling_config & 0xf) {
143 case 0:
144 radeon->tiling_info.num_channels = 1;
145 break;
146 case 1:
147 radeon->tiling_info.num_channels = 2;
148 break;
149 case 2:
150 radeon->tiling_info.num_channels = 4;
151 break;
152 case 3:
153 radeon->tiling_info.num_channels = 8;
154 break;
155 default:
156 return -EINVAL;
157 }
158
159 radeon->tiling_info.num_banks = (tiling_config & 0xf0) >> 4;
160
161 switch ((tiling_config & 0xf00) >> 8) {
162 case 0:
163 radeon->tiling_info.group_bytes = 256;
164 break;
165 case 1:
166 radeon->tiling_info.group_bytes = 512;
167 break;
168 default:
169 return -EINVAL;
170 }
171 return 0;
172 }
173
174 static int radeon_drm_get_tiling(struct radeon *radeon)
175 {
176 struct drm_radeon_info info;
177 int r;
178 uint32_t tiling_config = 0;
179
180 info.request = RADEON_INFO_TILING_CONFIG;
181 info.value = (uintptr_t)&tiling_config;
182 r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
183 sizeof(struct drm_radeon_info));
184
185 if (r)
186 return 0;
187
188 if (radeon->chip_class == R600 || radeon->chip_class == R700) {
189 r = r600_interpret_tiling(radeon, tiling_config);
190 } else {
191 r = eg_interpret_tiling(radeon, tiling_config);
192 }
193 return r;
194 }
195
196 static int radeon_get_clock_crystal_freq(struct radeon *radeon)
197 {
198 struct drm_radeon_info info;
199 uint32_t clock_crystal_freq;
200 int r;
201
202 info.request = RADEON_INFO_CLOCK_CRYSTAL_FREQ;
203 info.value = (uintptr_t)&clock_crystal_freq;
204 r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
205 sizeof(struct drm_radeon_info));
206 if (r)
207 return r;
208
209 radeon->clock_crystal_freq = clock_crystal_freq;
210 return 0;
211 }
212
213
214 static int radeon_get_num_backends(struct radeon *radeon)
215 {
216 struct drm_radeon_info info;
217 uint32_t num_backends;
218 int r;
219
220 info.request = RADEON_INFO_NUM_BACKENDS;
221 info.value = (uintptr_t)&num_backends;
222 r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
223 sizeof(struct drm_radeon_info));
224 if (r)
225 return r;
226
227 radeon->num_backends = num_backends;
228 return 0;
229 }
230
231
232 static int radeon_init_fence(struct radeon *radeon)
233 {
234 radeon->fence = 1;
235 radeon->fence_bo = r600_bo(radeon, 4096, 0, 0, 0);
236 if (radeon->fence_bo == NULL) {
237 return -ENOMEM;
238 }
239 radeon->cfence = r600_bo_map(radeon, radeon->fence_bo, PB_USAGE_UNSYNCHRONIZED, NULL);
240 *radeon->cfence = 0;
241 return 0;
242 }
243
244 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
245
246 static unsigned handle_hash(void *key)
247 {
248 return PTR_TO_UINT(key);
249 }
250
251 static int handle_compare(void *key1, void *key2)
252 {
253 return PTR_TO_UINT(key1) != PTR_TO_UINT(key2);
254 }
255
256 static struct radeon *radeon_new(int fd, unsigned device)
257 {
258 struct radeon *radeon;
259 int r;
260 drmVersionPtr version;
261
262 radeon = calloc(1, sizeof(*radeon));
263 if (radeon == NULL) {
264 return NULL;
265 }
266 radeon->fd = fd;
267 radeon->device = device;
268 radeon->refcount = 1;
269
270 version = drmGetVersion(radeon->fd);
271 if (version->version_major != 2) {
272 fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
273 "only compatible with 2.x.x\n", __FUNCTION__,
274 version->version_major, version->version_minor,
275 version->version_patchlevel);
276 drmFreeVersion(version);
277 exit(1);
278 }
279
280 radeon->minor_version = version->version_minor;
281
282 drmFreeVersion(version);
283
284 r = radeon_get_device(radeon);
285 if (r) {
286 fprintf(stderr, "Failed to get device id\n");
287 return radeon_decref(radeon);
288 }
289
290 radeon->family = radeon_family_from_device(radeon->device);
291 if (radeon->family == CHIP_UNKNOWN) {
292 fprintf(stderr, "Unknown chipset 0x%04X\n", radeon->device);
293 return radeon_decref(radeon);
294 }
295 /* setup class */
296 switch (radeon->family) {
297 case CHIP_R600:
298 case CHIP_RV610:
299 case CHIP_RV630:
300 case CHIP_RV670:
301 case CHIP_RV620:
302 case CHIP_RV635:
303 case CHIP_RS780:
304 case CHIP_RS880:
305 radeon->chip_class = R600;
306 /* set default group bytes, overridden by tiling info ioctl */
307 radeon->tiling_info.group_bytes = 256;
308 break;
309 case CHIP_RV770:
310 case CHIP_RV730:
311 case CHIP_RV710:
312 case CHIP_RV740:
313 radeon->chip_class = R700;
314 /* set default group bytes, overridden by tiling info ioctl */
315 radeon->tiling_info.group_bytes = 256;
316 break;
317 case CHIP_CEDAR:
318 case CHIP_REDWOOD:
319 case CHIP_JUNIPER:
320 case CHIP_CYPRESS:
321 case CHIP_HEMLOCK:
322 case CHIP_PALM:
323 case CHIP_BARTS:
324 case CHIP_TURKS:
325 case CHIP_CAICOS:
326 radeon->chip_class = EVERGREEN;
327 /* set default group bytes, overridden by tiling info ioctl */
328 radeon->tiling_info.group_bytes = 512;
329 break;
330 default:
331 fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
332 __func__, radeon->device);
333 break;
334 }
335
336 if (radeon_drm_get_tiling(radeon))
337 return NULL;
338
339 /* get the GPU counter frequency, failure is non fatal */
340 radeon_get_clock_crystal_freq(radeon);
341
342 if (radeon->minor_version >= 9)
343 radeon_get_num_backends(radeon);
344
345 radeon->bomgr = r600_bomgr_create(radeon, 1000000);
346 if (radeon->bomgr == NULL) {
347 return NULL;
348 }
349 r = radeon_init_fence(radeon);
350 if (r) {
351 radeon_decref(radeon);
352 return NULL;
353 }
354
355 radeon->bo_handles = util_hash_table_create(handle_hash, handle_compare);
356 pipe_mutex_init(radeon->bo_handles_mutex);
357 return radeon;
358 }
359
360 struct radeon *r600_drm_winsys_create(int drmfd)
361 {
362 return radeon_new(drmfd, 0);
363 }
364
365 struct radeon *radeon_decref(struct radeon *radeon)
366 {
367 if (radeon == NULL)
368 return NULL;
369 if (--radeon->refcount > 0) {
370 return NULL;
371 }
372
373 util_hash_table_destroy(radeon->bo_handles);
374 pipe_mutex_destroy(radeon->bo_handles_mutex);
375 if (radeon->fence_bo) {
376 r600_bo_reference(radeon, &radeon->fence_bo, NULL);
377 }
378
379 if (radeon->bomgr)
380 r600_bomgr_destroy(radeon->bomgr);
381
382 free(radeon);
383 return NULL;
384 }