2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
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:
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
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.
25 * Corbin Simpson <MostAwesomeDude@gmail.com>
26 * Joakim Sindholt <opensource@zhasha.com>
29 #include "r600_priv.h"
30 #include "r600_drm_public.h"
31 #include "util/u_memory.h"
32 #include <radeon_drm.h>
36 #ifndef RADEON_INFO_NUM_TILE_PIPES
37 #define RADEON_INFO_NUM_TILE_PIPES 0xb
40 #ifndef RADEON_INFO_BACKEND_MAP
41 #define RADEON_INFO_BACKEND_MAP 0xd
44 enum radeon_family
r600_get_family(struct radeon
*r600
)
49 enum chip_class
r600_get_family_class(struct radeon
*radeon
)
51 return radeon
->chip_class
;
54 struct r600_tiling_info
*r600_get_tiling_info(struct radeon
*radeon
)
56 return &radeon
->tiling_info
;
59 unsigned r600_get_clock_crystal_freq(struct radeon
*radeon
)
61 return radeon
->info
.r600_clock_crystal_freq
;
64 unsigned r600_get_num_backends(struct radeon
*radeon
)
66 return radeon
->info
.r600_num_backends
;
69 unsigned r600_get_num_tile_pipes(struct radeon
*radeon
)
71 return radeon
->num_tile_pipes
;
74 unsigned r600_get_backend_map(struct radeon
*radeon
)
76 return radeon
->backend_map
;
79 unsigned r600_get_minor_version(struct radeon
*radeon
)
81 return radeon
->info
.drm_minor
;
84 static int r600_interpret_tiling(struct radeon
*radeon
, uint32_t tiling_config
)
86 switch ((tiling_config
& 0xe) >> 1) {
88 radeon
->tiling_info
.num_channels
= 1;
91 radeon
->tiling_info
.num_channels
= 2;
94 radeon
->tiling_info
.num_channels
= 4;
97 radeon
->tiling_info
.num_channels
= 8;
103 switch ((tiling_config
& 0x30) >> 4) {
105 radeon
->tiling_info
.num_banks
= 4;
108 radeon
->tiling_info
.num_banks
= 8;
114 switch ((tiling_config
& 0xc0) >> 6) {
116 radeon
->tiling_info
.group_bytes
= 256;
119 radeon
->tiling_info
.group_bytes
= 512;
127 static int eg_interpret_tiling(struct radeon
*radeon
, uint32_t tiling_config
)
129 switch (tiling_config
& 0xf) {
131 radeon
->tiling_info
.num_channels
= 1;
134 radeon
->tiling_info
.num_channels
= 2;
137 radeon
->tiling_info
.num_channels
= 4;
140 radeon
->tiling_info
.num_channels
= 8;
146 switch ((tiling_config
& 0xf0) >> 4) {
148 radeon
->tiling_info
.num_banks
= 4;
151 radeon
->tiling_info
.num_banks
= 8;
154 radeon
->tiling_info
.num_banks
= 16;
161 switch ((tiling_config
& 0xf00) >> 8) {
163 radeon
->tiling_info
.group_bytes
= 256;
166 radeon
->tiling_info
.group_bytes
= 512;
174 static int radeon_drm_get_tiling(struct radeon
*radeon
)
176 uint32_t tiling_config
= radeon
->info
.r600_tiling_config
;
181 if (radeon
->chip_class
== R600
|| radeon
->chip_class
== R700
) {
182 return r600_interpret_tiling(radeon
, tiling_config
);
184 return eg_interpret_tiling(radeon
, tiling_config
);
188 static int radeon_get_num_tile_pipes(struct radeon
*radeon
)
190 struct drm_radeon_info info
= {};
191 uint32_t num_tile_pipes
= 0;
194 info
.request
= RADEON_INFO_NUM_TILE_PIPES
;
195 info
.value
= (uintptr_t)&num_tile_pipes
;
196 r
= drmCommandWriteRead(radeon
->info
.fd
, DRM_RADEON_INFO
, &info
,
197 sizeof(struct drm_radeon_info
));
201 radeon
->num_tile_pipes
= num_tile_pipes
;
205 static int radeon_get_backend_map(struct radeon
*radeon
)
207 struct drm_radeon_info info
= {};
208 uint32_t backend_map
= 0;
211 info
.request
= RADEON_INFO_BACKEND_MAP
;
212 info
.value
= (uintptr_t)&backend_map
;
213 r
= drmCommandWriteRead(radeon
->info
.fd
, DRM_RADEON_INFO
, &info
,
214 sizeof(struct drm_radeon_info
));
218 radeon
->backend_map
= backend_map
;
219 radeon
->backend_map_valid
= TRUE
;
224 static int radeon_init_fence(struct radeon
*radeon
)
227 radeon
->fence_bo
= r600_bo(radeon
, 4096, 0, 0, 0);
228 if (radeon
->fence_bo
== NULL
) {
231 radeon
->cfence
= r600_bo_map(radeon
, radeon
->fence_bo
, PIPE_TRANSFER_UNSYNCHRONIZED
, NULL
);
236 struct radeon
*radeon_create(struct radeon_winsys
*ws
)
239 struct radeon
*radeon
= CALLOC_STRUCT(radeon
);
240 if (radeon
== NULL
) {
245 ws
->query_info(ws
, &radeon
->info
);
247 radeon
->family
= radeon_family_from_device(radeon
->info
.pci_id
);
248 if (radeon
->family
== CHIP_UNKNOWN
) {
249 fprintf(stderr
, "Unknown chipset 0x%04X\n", radeon
->info
.pci_id
);
250 return radeon_destroy(radeon
);
253 switch (radeon
->family
) {
262 radeon
->chip_class
= R600
;
263 /* set default group bytes, overridden by tiling info ioctl */
264 radeon
->tiling_info
.group_bytes
= 256;
270 radeon
->chip_class
= R700
;
271 /* set default group bytes, overridden by tiling info ioctl */
272 radeon
->tiling_info
.group_bytes
= 256;
285 radeon
->chip_class
= EVERGREEN
;
286 /* set default group bytes, overridden by tiling info ioctl */
287 radeon
->tiling_info
.group_bytes
= 512;
290 radeon
->chip_class
= CAYMAN
;
291 /* set default group bytes, overridden by tiling info ioctl */
292 radeon
->tiling_info
.group_bytes
= 512;
295 fprintf(stderr
, "%s unknown or unsupported chipset 0x%04X\n",
296 __func__
, radeon
->info
.pci_id
);
300 if (radeon_drm_get_tiling(radeon
))
303 if (radeon
->info
.drm_minor
>= 11) {
304 radeon_get_num_tile_pipes(radeon
);
305 radeon_get_backend_map(radeon
);
308 r
= radeon_init_fence(radeon
);
310 radeon_destroy(radeon
);
317 struct radeon
*radeon_destroy(struct radeon
*radeon
)
322 if (radeon
->fence_bo
) {
323 r600_bo_reference(radeon
, &radeon
->fence_bo
, NULL
);