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 if (info
->drm_major
== 3 && info
->drm_minor
>= 17) {
161 r
= amdgpu_query_hw_ip_info(dev
, AMDGPU_HW_IP_VCN_DEC
, 0, &vcn_dec
);
163 fprintf(stderr
, "amdgpu: amdgpu_query_hw_ip_info(vcn_dec) failed.\n");
168 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_GFX_ME
, 0, 0,
169 &info
->me_fw_version
, &unused_feature
);
171 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(me) failed.\n");
175 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_GFX_PFP
, 0, 0,
176 &info
->pfp_fw_version
, &unused_feature
);
178 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(pfp) failed.\n");
182 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_GFX_CE
, 0, 0,
183 &info
->ce_fw_version
, &unused_feature
);
185 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(ce) failed.\n");
189 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_UVD
, 0, 0,
190 &uvd_version
, &uvd_feature
);
192 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(uvd) failed.\n");
196 r
= amdgpu_query_hw_ip_info(dev
, AMDGPU_HW_IP_VCE
, 0, &vce
);
198 fprintf(stderr
, "amdgpu: amdgpu_query_hw_ip_info(vce) failed.\n");
202 r
= amdgpu_query_firmware_version(dev
, AMDGPU_INFO_FW_VCE
, 0, 0,
203 &vce_version
, &vce_feature
);
205 fprintf(stderr
, "amdgpu: amdgpu_query_firmware_version(vce) failed.\n");
209 /* Set chip identification. */
210 info
->pci_id
= amdinfo
->asic_id
; /* TODO: is this correct? */
211 info
->vce_harvest_config
= amdinfo
->vce_harvest_config
;
213 switch (info
->pci_id
) {
214 #define CHIPSET(pci_id, name, cfamily) case pci_id: info->family = CHIP_##cfamily; break;
215 #include "pci_ids/radeonsi_pci_ids.h"
219 fprintf(stderr
, "amdgpu: Invalid PCI ID.\n");
223 if (info
->family
>= CHIP_VEGA10
)
224 info
->chip_class
= GFX9
;
225 else if (info
->family
>= CHIP_TONGA
)
226 info
->chip_class
= VI
;
227 else if (info
->family
>= CHIP_BONAIRE
)
228 info
->chip_class
= CIK
;
229 else if (info
->family
>= CHIP_TAHITI
)
230 info
->chip_class
= SI
;
232 fprintf(stderr
, "amdgpu: Unknown family.\n");
236 /* Set which chips have dedicated VRAM. */
237 info
->has_dedicated_vram
=
238 !(amdinfo
->ids_flags
& AMDGPU_IDS_FLAGS_FUSION
);
240 /* Set hardware information. */
241 info
->gart_size
= gtt
.heap_size
;
242 info
->vram_size
= vram
.heap_size
;
243 info
->vram_vis_size
= vram_vis
.heap_size
;
244 /* The kernel can split large buffers in VRAM but not in GTT, so large
245 * allocations can fail or cause buffer movement failures in the kernel.
247 info
->max_alloc_size
= MIN2(info
->vram_size
* 0.9, info
->gart_size
* 0.7);
248 /* convert the shader clock from KHz to MHz */
249 info
->max_shader_clock
= amdinfo
->max_engine_clk
/ 1000;
250 info
->max_se
= amdinfo
->num_shader_engines
;
251 info
->max_sh_per_se
= amdinfo
->num_shader_arrays_per_engine
;
252 info
->has_hw_decode
=
253 (uvd
.available_rings
!= 0) || (vcn_dec
.available_rings
!= 0);
254 info
->uvd_fw_version
=
255 uvd
.available_rings
? uvd_version
: 0;
256 info
->vce_fw_version
=
257 vce
.available_rings
? vce_version
: 0;
258 info
->has_userptr
= true;
259 info
->num_render_backends
= amdinfo
->rb_pipes
;
260 info
->clock_crystal_freq
= amdinfo
->gpu_counter_freq
;
261 info
->tcc_cache_line_size
= 64; /* TC L2 line size on GCN */
262 if (info
->chip_class
== GFX9
) {
263 info
->num_tile_pipes
= 1 << G_0098F8_NUM_PIPES(amdinfo
->gb_addr_cfg
);
264 info
->pipe_interleave_bytes
=
265 256 << G_0098F8_PIPE_INTERLEAVE_SIZE_GFX9(amdinfo
->gb_addr_cfg
);
267 info
->num_tile_pipes
= cik_get_num_tile_pipes(amdinfo
);
268 info
->pipe_interleave_bytes
=
269 256 << G_0098F8_PIPE_INTERLEAVE_SIZE_GFX6(amdinfo
->gb_addr_cfg
);
271 info
->has_virtual_memory
= true;
273 assert(util_is_power_of_two(dma
.available_rings
+ 1));
274 assert(util_is_power_of_two(compute
.available_rings
+ 1));
276 info
->num_sdma_rings
= util_bitcount(dma
.available_rings
);
277 info
->num_compute_rings
= util_bitcount(compute
.available_rings
);
279 /* Get the number of good compute units. */
280 info
->num_good_compute_units
= 0;
281 for (i
= 0; i
< info
->max_se
; i
++)
282 for (j
= 0; j
< info
->max_sh_per_se
; j
++)
283 info
->num_good_compute_units
+=
284 util_bitcount(amdinfo
->cu_bitmap
[i
][j
]);
286 memcpy(info
->si_tile_mode_array
, amdinfo
->gb_tile_mode
,
287 sizeof(amdinfo
->gb_tile_mode
));
288 info
->enabled_rb_mask
= amdinfo
->enabled_rb_pipes_mask
;
290 memcpy(info
->cik_macrotile_mode_array
, amdinfo
->gb_macro_tile_mode
,
291 sizeof(amdinfo
->gb_macro_tile_mode
));
293 info
->pte_fragment_size
= alignment_info
.size_local
;
294 info
->gart_page_size
= alignment_info
.size_remote
;
296 if (info
->chip_class
== SI
)
297 info
->gfx_ib_pad_with_type2
= TRUE
;