2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 * based on amdgpu winsys.
5 * Copyright © 2011 Marek Olšák <maraeo@gmail.com>
6 * Copyright © 2015 Advanced Micro Devices, Inc.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 #include "radv_amdgpu_winsys.h"
28 #include "radv_amdgpu_winsys_public.h"
29 #include "radv_amdgpu_surface.h"
30 #include "radv_debug.h"
31 #include "amdgpu_id.h"
36 #include <amdgpu_drm.h>
38 #include "radv_amdgpu_cs.h"
39 #include "radv_amdgpu_bo.h"
40 #include "radv_amdgpu_surface.h"
42 #define CIK_TILE_MODE_COLOR_2D 14
44 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
45 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
46 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
47 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
48 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
49 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
50 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
51 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
52 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
53 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
54 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
55 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
56 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
57 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
58 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
60 static unsigned radv_cik_get_num_tile_pipes(struct amdgpu_gpu_info
*info
)
62 unsigned mode2d
= info
->gb_tile_mode
[CIK_TILE_MODE_COLOR_2D
];
64 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(mode2d
)) {
65 case CIK__PIPE_CONFIG__ADDR_SURF_P2
:
67 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16
:
68 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16
:
69 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32
:
70 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32
:
72 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16
:
73 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16
:
74 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16
:
75 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16
:
76 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16
:
77 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32
:
78 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32
:
80 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16
:
81 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16
:
84 fprintf(stderr
, "Invalid CIK pipe configuration, assuming P2\n");
85 assert(!"this should never occur");
91 get_chip_name(enum radeon_family family
)
94 case CHIP_TAHITI
: return "AMD RADV TAHITI";
95 case CHIP_PITCAIRN
: return "AMD RADV PITCAIRN";
96 case CHIP_VERDE
: return "AMD RADV CAPE VERDE";
97 case CHIP_OLAND
: return "AMD RADV OLAND";
98 case CHIP_HAINAN
: return "AMD RADV HAINAN";
99 case CHIP_BONAIRE
: return "AMD RADV BONAIRE";
100 case CHIP_KAVERI
: return "AMD RADV KAVERI";
101 case CHIP_KABINI
: return "AMD RADV KABINI";
102 case CHIP_HAWAII
: return "AMD RADV HAWAII";
103 case CHIP_MULLINS
: return "AMD RADV MULLINS";
104 case CHIP_TONGA
: return "AMD RADV TONGA";
105 case CHIP_ICELAND
: return "AMD RADV ICELAND";
106 case CHIP_CARRIZO
: return "AMD RADV CARRIZO";
107 case CHIP_FIJI
: return "AMD RADV FIJI";
108 case CHIP_POLARIS10
: return "AMD RADV POLARIS10";
109 case CHIP_POLARIS11
: return "AMD RADV POLARIS11";
110 case CHIP_POLARIS12
: return "AMD RADV POLARIS12";
111 case CHIP_STONEY
: return "AMD RADV STONEY";
112 default: return "AMD RADV unknown";
118 do_winsys_init(struct radv_amdgpu_winsys
*ws
, int fd
)
120 struct amdgpu_buffer_size_alignments alignment_info
= {};
121 struct amdgpu_heap_info vram
, visible_vram
, gtt
;
122 struct drm_amdgpu_info_hw_ip dma
= {};
123 struct drm_amdgpu_info_hw_ip compute
= {};
124 drmDevicePtr devinfo
;
128 r
= drmGetDevice2(fd
, 0, &devinfo
);
130 fprintf(stderr
, "amdgpu: drmGetDevice2 failed.\n");
133 ws
->info
.pci_domain
= devinfo
->businfo
.pci
->domain
;
134 ws
->info
.pci_bus
= devinfo
->businfo
.pci
->bus
;
135 ws
->info
.pci_dev
= devinfo
->businfo
.pci
->dev
;
136 ws
->info
.pci_func
= devinfo
->businfo
.pci
->func
;
137 drmFreeDevice(&devinfo
);
139 /* Query hardware and driver information. */
140 r
= amdgpu_query_gpu_info(ws
->dev
, &ws
->amdinfo
);
142 fprintf(stderr
, "amdgpu: amdgpu_query_gpu_info failed.\n");
146 r
= amdgpu_query_buffer_size_alignment(ws
->dev
, &alignment_info
);
148 fprintf(stderr
, "amdgpu: amdgpu_query_buffer_size_alignment failed.\n");
152 r
= amdgpu_query_heap_info(ws
->dev
, AMDGPU_GEM_DOMAIN_VRAM
, 0, &vram
);
154 fprintf(stderr
, "amdgpu: amdgpu_query_heap_info(vram) failed.\n");
158 r
= amdgpu_query_heap_info(ws
->dev
, AMDGPU_GEM_DOMAIN_VRAM
,
159 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
, &visible_vram
);
161 fprintf(stderr
, "amdgpu: amdgpu_query_heap_info(visible_vram) failed.\n");
165 r
= amdgpu_query_heap_info(ws
->dev
, AMDGPU_GEM_DOMAIN_GTT
, 0, >t
);
167 fprintf(stderr
, "amdgpu: amdgpu_query_heap_info(gtt) failed.\n");
171 r
= amdgpu_query_hw_ip_info(ws
->dev
, AMDGPU_HW_IP_DMA
, 0, &dma
);
173 fprintf(stderr
, "amdgpu: amdgpu_query_hw_ip_info(dma) failed.\n");
177 r
= amdgpu_query_hw_ip_info(ws
->dev
, AMDGPU_HW_IP_COMPUTE
, 0, &compute
);
179 fprintf(stderr
, "amdgpu: amdgpu_query_hw_ip_info(compute) failed.\n");
182 ws
->info
.pci_id
= ws
->amdinfo
.asic_id
; /* TODO: is this correct? */
183 ws
->info
.vce_harvest_config
= ws
->amdinfo
.vce_harvest_config
;
185 switch (ws
->info
.pci_id
) {
186 #define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; break;
187 #include "pci_ids/radeonsi_pci_ids.h"
190 fprintf(stderr
, "amdgpu: Invalid PCI ID.\n");
194 if (ws
->info
.family
>= CHIP_TONGA
)
195 ws
->info
.chip_class
= VI
;
196 else if (ws
->info
.family
>= CHIP_BONAIRE
)
197 ws
->info
.chip_class
= CIK
;
198 else if (ws
->info
.family
>= CHIP_TAHITI
)
199 ws
->info
.chip_class
= SI
;
201 fprintf(stderr
, "amdgpu: Unknown family.\n");
205 /* family and rev_id are for addrlib */
206 switch (ws
->info
.family
) {
208 ws
->family
= FAMILY_SI
;
209 ws
->rev_id
= SI_TAHITI_P_A0
;
212 ws
->family
= FAMILY_SI
;
213 ws
->rev_id
= SI_PITCAIRN_PM_A0
;
216 ws
->family
= FAMILY_SI
;
217 ws
->rev_id
= SI_CAPEVERDE_M_A0
;
220 ws
->family
= FAMILY_SI
;
221 ws
->rev_id
= SI_OLAND_M_A0
;
224 ws
->family
= FAMILY_SI
;
225 ws
->rev_id
= SI_HAINAN_V_A0
;
228 ws
->family
= FAMILY_CI
;
229 ws
->rev_id
= CI_BONAIRE_M_A0
;
232 ws
->family
= FAMILY_KV
;
233 ws
->rev_id
= KV_SPECTRE_A0
;
236 ws
->family
= FAMILY_KV
;
237 ws
->rev_id
= KB_KALINDI_A0
;
240 ws
->family
= FAMILY_CI
;
241 ws
->rev_id
= CI_HAWAII_P_A0
;
244 ws
->family
= FAMILY_KV
;
245 ws
->rev_id
= ML_GODAVARI_A0
;
248 ws
->family
= FAMILY_VI
;
249 ws
->rev_id
= VI_TONGA_P_A0
;
252 ws
->family
= FAMILY_VI
;
253 ws
->rev_id
= VI_ICELAND_M_A0
;
256 ws
->family
= FAMILY_CZ
;
257 ws
->rev_id
= CARRIZO_A0
;
260 ws
->family
= FAMILY_CZ
;
261 ws
->rev_id
= STONEY_A0
;
264 ws
->family
= FAMILY_VI
;
265 ws
->rev_id
= VI_FIJI_P_A0
;
268 ws
->family
= FAMILY_VI
;
269 ws
->rev_id
= VI_POLARIS10_P_A0
;
272 ws
->family
= FAMILY_VI
;
273 ws
->rev_id
= VI_POLARIS11_M_A0
;
276 ws
->family
= FAMILY_VI
;
277 ws
->rev_id
= VI_POLARIS12_V_A0
;
280 fprintf(stderr
, "amdgpu: Unknown family.\n");
284 ws
->addrlib
= radv_amdgpu_addr_create(&ws
->amdinfo
, ws
->family
, ws
->rev_id
, ws
->info
.chip_class
);
286 fprintf(stderr
, "amdgpu: Cannot create addrlib.\n");
290 assert(util_is_power_of_two(dma
.available_rings
+ 1));
291 assert(util_is_power_of_two(compute
.available_rings
+ 1));
293 /* Set hardware information. */
294 ws
->info
.name
= get_chip_name(ws
->info
.family
);
295 ws
->info
.gart_size
= gtt
.heap_size
;
296 ws
->info
.vram_size
= vram
.heap_size
;
297 ws
->info
.visible_vram_size
= visible_vram
.heap_size
;
298 /* convert the shader clock from KHz to MHz */
299 ws
->info
.max_shader_clock
= ws
->amdinfo
.max_engine_clk
/ 1000;
300 ws
->info
.max_se
= ws
->amdinfo
.num_shader_engines
;
301 ws
->info
.max_sh_per_se
= ws
->amdinfo
.num_shader_arrays_per_engine
;
302 ws
->info
.has_uvd
= 0;
303 ws
->info
.vce_fw_version
= 0;
304 ws
->info
.has_userptr
= TRUE
;
305 ws
->info
.num_render_backends
= ws
->amdinfo
.rb_pipes
;
306 ws
->info
.clock_crystal_freq
= ws
->amdinfo
.gpu_counter_freq
;
307 ws
->info
.num_tile_pipes
= radv_cik_get_num_tile_pipes(&ws
->amdinfo
);
308 ws
->info
.pipe_interleave_bytes
= 256 << ((ws
->amdinfo
.gb_addr_cfg
>> 4) & 0x7);
309 ws
->info
.has_virtual_memory
= TRUE
;
310 ws
->info
.sdma_rings
= MIN2(util_bitcount(dma
.available_rings
),
312 ws
->info
.compute_rings
= MIN2(util_bitcount(compute
.available_rings
),
315 /* Get the number of good compute units. */
316 ws
->info
.num_good_compute_units
= 0;
317 for (i
= 0; i
< ws
->info
.max_se
; i
++)
318 for (j
= 0; j
< ws
->info
.max_sh_per_se
; j
++)
319 ws
->info
.num_good_compute_units
+=
320 util_bitcount(ws
->amdinfo
.cu_bitmap
[i
][j
]);
322 memcpy(ws
->info
.si_tile_mode_array
, ws
->amdinfo
.gb_tile_mode
,
323 sizeof(ws
->amdinfo
.gb_tile_mode
));
324 ws
->info
.enabled_rb_mask
= ws
->amdinfo
.enabled_rb_pipes_mask
;
326 memcpy(ws
->info
.cik_macrotile_mode_array
, ws
->amdinfo
.gb_macro_tile_mode
,
327 sizeof(ws
->amdinfo
.gb_macro_tile_mode
));
329 ws
->info
.gart_page_size
= alignment_info
.size_remote
;
331 if (ws
->info
.chip_class
== SI
)
332 ws
->info
.gfx_ib_pad_with_type2
= TRUE
;
334 ws
->use_ib_bos
= ws
->family
>= FAMILY_CI
;
340 static void radv_amdgpu_winsys_query_info(struct radeon_winsys
*rws
,
341 struct radeon_info
*info
)
343 *info
= ((struct radv_amdgpu_winsys
*)rws
)->info
;
346 static void radv_amdgpu_winsys_destroy(struct radeon_winsys
*rws
)
348 struct radv_amdgpu_winsys
*ws
= (struct radv_amdgpu_winsys
*)rws
;
350 AddrDestroy(ws
->addrlib
);
351 amdgpu_device_deinitialize(ws
->dev
);
355 struct radeon_winsys
*
356 radv_amdgpu_winsys_create(int fd
, uint32_t debug_flags
)
358 uint32_t drm_major
, drm_minor
, r
;
359 amdgpu_device_handle dev
;
360 struct radv_amdgpu_winsys
*ws
;
362 r
= amdgpu_device_initialize(fd
, &drm_major
, &drm_minor
, &dev
);
366 ws
= calloc(1, sizeof(struct radv_amdgpu_winsys
));
371 ws
->info
.drm_major
= drm_major
;
372 ws
->info
.drm_minor
= drm_minor
;
373 if (!do_winsys_init(ws
, fd
))
376 ws
->debug_all_bos
= !!(debug_flags
& RADV_DEBUG_ALL_BOS
);
377 if (debug_flags
& RADV_DEBUG_NO_IBS
)
378 ws
->use_ib_bos
= false;
380 LIST_INITHEAD(&ws
->global_bo_list
);
381 pthread_mutex_init(&ws
->global_bo_list_lock
, NULL
);
382 ws
->base
.query_info
= radv_amdgpu_winsys_query_info
;
383 ws
->base
.destroy
= radv_amdgpu_winsys_destroy
;
384 radv_amdgpu_bo_init_functions(ws
);
385 radv_amdgpu_cs_init_functions(ws
);
386 radv_amdgpu_surface_init_functions(ws
);
393 amdgpu_device_deinitialize(dev
);