ee262c3ea52a74c946e0fab8095bd0495b24c7f0
[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 <pipebuffer/pb_bufmgr.h>
34 #include "r600.h"
35 #include "r600_priv.h"
36 #include "r600_drm_public.h"
37 #include "xf86drm.h"
38 #include "radeon_drm.h"
39
40 #ifndef RADEON_INFO_TILING_CONFIG
41 #define RADEON_INFO_TILING_CONFIG 0x6
42 #endif
43
44 static struct radeon *radeon_new(int fd, unsigned device);
45
46 enum radeon_family r600_get_family(struct radeon *r600)
47 {
48 return r600->family;
49 }
50
51 enum chip_class r600_get_family_class(struct radeon *radeon)
52 {
53 return radeon->chip_class;
54 }
55
56 struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon)
57 {
58 return &radeon->tiling_info;
59 }
60
61 static int radeon_get_device(struct radeon *radeon)
62 {
63 struct drm_radeon_info info;
64 int r;
65
66 radeon->device = 0;
67 info.request = RADEON_INFO_DEVICE_ID;
68 info.value = (uintptr_t)&radeon->device;
69 r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
70 sizeof(struct drm_radeon_info));
71 return r;
72 }
73
74 static int radeon_drm_get_tiling(struct radeon *radeon)
75 {
76 struct drm_radeon_info info;
77 int r;
78 uint32_t tiling_config;
79
80 info.request = RADEON_INFO_TILING_CONFIG;
81 info.value = (uintptr_t)&tiling_config;
82 r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
83 sizeof(struct drm_radeon_info));
84
85 if (r)
86 return 0;
87
88 switch ((tiling_config & 0xe) >> 1) {
89 case 0:
90 radeon->tiling_info.num_channels = 1;
91 break;
92 case 1:
93 radeon->tiling_info.num_channels = 2;
94 break;
95 case 2:
96 radeon->tiling_info.num_channels = 4;
97 break;
98 case 3:
99 radeon->tiling_info.num_channels = 8;
100 break;
101 default:
102 return -EINVAL;
103 }
104
105 switch ((tiling_config & 0x30) >> 4) {
106 case 0:
107 radeon->tiling_info.num_banks = 4;
108 break;
109 case 1:
110 radeon->tiling_info.num_banks = 8;
111 break;
112 default:
113 return -EINVAL;
114
115 }
116 switch ((tiling_config & 0xc0) >> 6) {
117 case 0:
118 radeon->tiling_info.group_bytes = 256;
119 break;
120 case 1:
121 radeon->tiling_info.group_bytes = 512;
122 break;
123 default:
124 return -EINVAL;
125 }
126 return 0;
127 }
128
129 static int radeon_init_fence(struct radeon *radeon)
130 {
131 radeon->fence = 1;
132 radeon->fence_bo = r600_bo(radeon, 4096, 0, 0, 0);
133 if (radeon->fence_bo == NULL) {
134 return -ENOMEM;
135 }
136 radeon->cfence = r600_bo_map(radeon, radeon->fence_bo, PB_USAGE_UNSYNCHRONIZED, NULL);
137 *radeon->cfence = 0;
138 return 0;
139 }
140
141 static struct radeon *radeon_new(int fd, unsigned device)
142 {
143 struct radeon *radeon;
144 int r;
145
146 radeon = calloc(1, sizeof(*radeon));
147 if (radeon == NULL) {
148 return NULL;
149 }
150 radeon->fd = fd;
151 radeon->device = device;
152 radeon->refcount = 1;
153 if (fd >= 0) {
154 r = radeon_get_device(radeon);
155 if (r) {
156 fprintf(stderr, "Failed to get device id\n");
157 return radeon_decref(radeon);
158 }
159 }
160 radeon->family = radeon_family_from_device(radeon->device);
161 if (radeon->family == CHIP_UNKNOWN) {
162 fprintf(stderr, "Unknown chipset 0x%04X\n", radeon->device);
163 return radeon_decref(radeon);
164 }
165 /* setup class */
166 switch (radeon->family) {
167 case CHIP_R600:
168 case CHIP_RV610:
169 case CHIP_RV630:
170 case CHIP_RV670:
171 case CHIP_RV620:
172 case CHIP_RV635:
173 case CHIP_RS780:
174 case CHIP_RS880:
175 radeon->chip_class = R600;
176 /* set default group bytes, overridden by tiling info ioctl */
177 radeon->tiling_info.group_bytes = 256;
178 break;
179 case CHIP_RV770:
180 case CHIP_RV730:
181 case CHIP_RV710:
182 case CHIP_RV740:
183 radeon->chip_class = R700;
184 /* set default group bytes, overridden by tiling info ioctl */
185 radeon->tiling_info.group_bytes = 256;
186 break;
187 case CHIP_CEDAR:
188 case CHIP_REDWOOD:
189 case CHIP_JUNIPER:
190 case CHIP_CYPRESS:
191 case CHIP_HEMLOCK:
192 case CHIP_PALM:
193 case CHIP_BARTS:
194 case CHIP_TURKS:
195 case CHIP_CAICOS:
196 radeon->chip_class = EVERGREEN;
197 /* set default group bytes, overridden by tiling info ioctl */
198 radeon->tiling_info.group_bytes = 512;
199 break;
200 default:
201 fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
202 __func__, radeon->device);
203 break;
204 }
205
206 if (radeon->chip_class == R600 || radeon->chip_class == R700) {
207 if (radeon_drm_get_tiling(radeon))
208 return NULL;
209 }
210 radeon->bomgr = r600_bomgr_create(radeon, 1000000);
211 if (radeon->bomgr == NULL) {
212 return NULL;
213 }
214 r = radeon_init_fence(radeon);
215 if (r) {
216 radeon_decref(radeon);
217 return NULL;
218 }
219 return radeon;
220 }
221
222 struct radeon *r600_drm_winsys_create(int drmfd)
223 {
224 return radeon_new(drmfd, 0);
225 }
226
227 struct radeon *radeon_decref(struct radeon *radeon)
228 {
229 if (radeon == NULL)
230 return NULL;
231 if (--radeon->refcount > 0) {
232 return NULL;
233 }
234
235 if (radeon->fence_bo) {
236 r600_bo_reference(radeon, &radeon->fence_bo, NULL);
237 }
238
239 if (radeon->bomgr)
240 r600_bomgr_destroy(radeon->bomgr);
241
242 if (radeon->fd >= 0)
243 drmClose(radeon->fd);
244
245 free(radeon);
246 return NULL;
247 }