2 * Copyright © 2017 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
14 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
16 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
26 #include "ac_gpu_info.h"
30 #include "util/u_math.h"
35 #include <amdgpu_drm.h>
37 #define CIK_TILE_MODE_COLOR_2D 14
39 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
40 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
41 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
42 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
43 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
44 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
45 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
46 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
47 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
48 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
49 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
50 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
51 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
52 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
53 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
55 static unsigned cik_get_num_tile_pipes(struct amdgpu_gpu_info
*info
)
57 unsigned mode2d
= info
->gb_tile_mode
[CIK_TILE_MODE_COLOR_2D
];
59 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(mode2d
)) {
60 case CIK__PIPE_CONFIG__ADDR_SURF_P2
:
62 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16
:
63 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16
:
64 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32
:
65 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32
:
67 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16
:
68 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16
:
69 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16
:
70 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16
:
71 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16
:
72 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32
:
73 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32
:
75 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16
:
76 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16
:
79 fprintf(stderr
, "Invalid CIK pipe configuration, assuming P2\n");
80 assert(!"this should never occur");
85 bool ac_query_gpu_info(int fd
, amdgpu_device_handle dev
,
86 struct radeon_info
*info
,
87 struct amdgpu_gpu_info
*amdinfo
)
89 struct amdgpu_buffer_size_alignments alignment_info
= {};
90 struct amdgpu_heap_info vram
, vram_vis
, gtt
;
91 struct drm_amdgpu_info_hw_ip dma
= {}, compute
= {}, uvd
= {}, vce
= {}, vcn_dec
= {};
92 uint32_t vce_version
= 0, vce_feature
= 0, uvd_version
= 0, uvd_feature
= 0;
93 uint32_t unused_feature
;
98 r
= drmGetDevice2(fd
, 0, &devinfo
);
100 fprintf(stderr
, "amdgpu: drmGetDevice2 failed.\n");
103 info
->pci_domain
= devinfo
->businfo
.pci
->domain
;
104 info
->pci_bus
= devinfo
->businfo
.pci
->bus
;
105 info
->pci_dev
= devinfo
->businfo
.pci
->dev
;
106 info
->pci_func
= devinfo
->businfo
.pci
->func
;
107 drmFreeDevice(&devinfo
);
109 /* Query hardware and driver information. */
110 r
= amdgpu_query_gpu_info(dev
, amdinfo
);
112 fprintf(stderr
, "amdgpu: amdgpu_query_gpu_info failed.\n");
116 r
= amdgpu_query_buffer_size_alignment(dev
, &alignment_info
);
118 fprintf(stderr
, "amdgpu: amdgpu_query_buffer_size_alignment failed.\n");
122 r
= amdgpu_query_heap_info(dev
, AMDGPU_GEM_DOMAIN_VRAM
, 0, &vram
);
124 fprintf(stderr
, "amdgpu: amdgpu_query_heap_info(vram) failed.\n");
128 r
= amdgpu_query_heap_info(dev
, AMDGPU_GEM_DOMAIN_VRAM
,
129 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
,
132 fprintf(stderr
, "amdgpu: amdgpu_query_heap_info(vram_vis) failed.\n");
136 r
= amdgpu_query_heap_info(dev
, AMDGPU_GEM_DOMAIN_GTT
, 0, >t
);
138 fprintf(stderr
, "amdgpu: amdgpu_query_heap_info(gtt) failed.\n");
142 r
= amdgpu_query_hw_ip_info(dev
, AMDGPU_HW_IP_DMA
, 0, &dma
);
144 fprintf(stderr
, "amdgpu: amdgpu_query_hw_ip_info(dma) failed.\n");
148 r
= amdgpu_query_hw_ip_info(dev
, AMDGPU_HW_IP_COMPUTE
, 0, &compute
);
150 fprintf(stderr
, "amdgpu: amdgpu_query_hw_ip_info(compute) failed.\n");
154 r
= amdgpu_query_hw_ip_info(dev
, AMDGPU_HW_IP_UVD
, 0, &uvd
);
156 fprintf(stderr
, "amdgpu: amdgpu_query_hw_ip_info(uvd) failed.\n");
160 r
= amdgpu_query_hw_ip_info(dev
, AMDGPU_HW_IP_VCN_DEC
, 0, &vcn_dec
);
162 fprintf(stderr
, "amdgpu: amdgpu_query_hw_ip_info(vcn_dec) failed.\n");
166 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_GFX_ME
, 0, 0,
167 &info
->me_fw_version
, &unused_feature
);
169 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(me) failed.\n");
173 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_GFX_PFP
, 0, 0,
174 &info
->pfp_fw_version
, &unused_feature
);
176 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(pfp) failed.\n");
180 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_GFX_CE
, 0, 0,
181 &info
->ce_fw_version
, &unused_feature
);
183 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(ce) failed.\n");
187 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_UVD
, 0, 0,
188 &uvd_version
, &uvd_feature
);
190 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(uvd) failed.\n");
194 r
= amdgpu_query_hw_ip_info(dev
, AMDGPU_HW_IP_VCE
, 0, &vce
);
196 fprintf(stderr
, "amdgpu: amdgpu_query_hw_ip_info(vce) failed.\n");
200 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_VCE
, 0, 0,
201 &vce_version
, &vce_feature
);
203 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(vce) failed.\n");
207 /* Set chip identification. */
208 info
->pci_id
= amdinfo
->asic_id
; /* TODO: is this correct? */
209 info
->vce_harvest_config
= amdinfo
->vce_harvest_config
;
211 switch (info
->pci_id
) {
212 #define CHIPSET(pci_id, name, cfamily) case pci_id: info->family = CHIP_##cfamily; break;
213 #include "pci_ids/radeonsi_pci_ids.h"
217 fprintf(stderr
, "amdgpu: Invalid PCI ID.\n");
221 if (info
->family
>= CHIP_VEGA10
)
222 info
->chip_class
= GFX9
;
223 else if (info
->family
>= CHIP_TONGA
)
224 info
->chip_class
= VI
;
225 else if (info
->family
>= CHIP_BONAIRE
)
226 info
->chip_class
= CIK
;
227 else if (info
->family
>= CHIP_TAHITI
)
228 info
->chip_class
= SI
;
230 fprintf(stderr
, "amdgpu: Unknown family.\n");
234 /* Set which chips have dedicated VRAM. */
235 info
->has_dedicated_vram
=
236 !(amdinfo
->ids_flags
& AMDGPU_IDS_FLAGS_FUSION
);
238 /* Set hardware information. */
239 info
->gart_size
= gtt
.heap_size
;
240 info
->vram_size
= vram
.heap_size
;
241 info
->vram_vis_size
= vram_vis
.heap_size
;
242 /* The kernel can split large buffers in VRAM but not in GTT, so large
243 * allocations can fail or cause buffer movement failures in the kernel.
245 info
->max_alloc_size
= MIN2(info
->vram_size
* 0.9, info
->gart_size
* 0.7);
246 /* convert the shader clock from KHz to MHz */
247 info
->max_shader_clock
= amdinfo
->max_engine_clk
/ 1000;
248 info
->max_se
= amdinfo
->num_shader_engines
;
249 info
->max_sh_per_se
= amdinfo
->num_shader_arrays_per_engine
;
250 info
->has_hw_decode
= uvd
.available_rings
!= 0;
251 info
->has_hw_decode
=
252 (uvd
.available_rings
!= 0) || (vcn_dec
.available_rings
!= 0);
253 info
->uvd_fw_version
=
254 uvd
.available_rings
? uvd_version
: 0;
255 info
->vce_fw_version
=
256 vce
.available_rings
? vce_version
: 0;
257 info
->has_userptr
= true;
258 info
->num_render_backends
= amdinfo
->rb_pipes
;
259 info
->clock_crystal_freq
= amdinfo
->gpu_counter_freq
;
260 info
->tcc_cache_line_size
= 64; /* TC L2 line size on GCN */
261 if (info
->chip_class
== GFX9
) {
262 info
->num_tile_pipes
= 1 << G_0098F8_NUM_PIPES(amdinfo
->gb_addr_cfg
);
263 info
->pipe_interleave_bytes
=
264 256 << G_0098F8_PIPE_INTERLEAVE_SIZE_GFX9(amdinfo
->gb_addr_cfg
);
266 info
->num_tile_pipes
= cik_get_num_tile_pipes(amdinfo
);
267 info
->pipe_interleave_bytes
=
268 256 << G_0098F8_PIPE_INTERLEAVE_SIZE_GFX6(amdinfo
->gb_addr_cfg
);
270 info
->has_virtual_memory
= true;
272 assert(util_is_power_of_two(dma
.available_rings
+ 1));
273 assert(util_is_power_of_two(compute
.available_rings
+ 1));
275 info
->num_sdma_rings
= util_bitcount(dma
.available_rings
);
276 info
->num_compute_rings
= util_bitcount(compute
.available_rings
);
278 /* Get the number of good compute units. */
279 info
->num_good_compute_units
= 0;
280 for (i
= 0; i
< info
->max_se
; i
++)
281 for (j
= 0; j
< info
->max_sh_per_se
; j
++)
282 info
->num_good_compute_units
+=
283 util_bitcount(amdinfo
->cu_bitmap
[i
][j
]);
285 memcpy(info
->si_tile_mode_array
, amdinfo
->gb_tile_mode
,
286 sizeof(amdinfo
->gb_tile_mode
));
287 info
->enabled_rb_mask
= amdinfo
->enabled_rb_pipes_mask
;
289 memcpy(info
->cik_macrotile_mode_array
, amdinfo
->gb_macro_tile_mode
,
290 sizeof(amdinfo
->gb_macro_tile_mode
));
292 info
->pte_fragment_size
= alignment_info
.size_local
;
293 info
->gart_page_size
= alignment_info
.size_remote
;
295 if (info
->chip_class
== SI
)
296 info
->gfx_ib_pad_with_type2
= TRUE
;