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