amdgpu_gpu_info.c revision 037b3c26
13f012e29Smrg/* 23f012e29Smrg * Copyright © 2014 Advanced Micro Devices, Inc. 33f012e29Smrg * All Rights Reserved. 43f012e29Smrg * 53f012e29Smrg * Permission is hereby granted, free of charge, to any person obtaining a 63f012e29Smrg * copy of this software and associated documentation files (the "Software"), 73f012e29Smrg * to deal in the Software without restriction, including without limitation 83f012e29Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 93f012e29Smrg * and/or sell copies of the Software, and to permit persons to whom the 103f012e29Smrg * Software is furnished to do so, subject to the following conditions: 113f012e29Smrg * 123f012e29Smrg * The above copyright notice and this permission notice shall be included in 133f012e29Smrg * all copies or substantial portions of the Software. 143f012e29Smrg * 153f012e29Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 163f012e29Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 173f012e29Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 183f012e29Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 193f012e29Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 203f012e29Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 213f012e29Smrg * OTHER DEALINGS IN THE SOFTWARE. 223f012e29Smrg * 233f012e29Smrg */ 243f012e29Smrg 253f012e29Smrg#ifdef HAVE_CONFIG_H 263f012e29Smrg#include "config.h" 273f012e29Smrg#endif 283f012e29Smrg 293f012e29Smrg#include <errno.h> 303f012e29Smrg#include <string.h> 313f012e29Smrg 323f012e29Smrg#include "amdgpu.h" 333f012e29Smrg#include "amdgpu_drm.h" 343f012e29Smrg#include "amdgpu_internal.h" 353f012e29Smrg#include "xf86drm.h" 363f012e29Smrg 373f012e29Smrgint amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id, 383f012e29Smrg unsigned size, void *value) 393f012e29Smrg{ 403f012e29Smrg struct drm_amdgpu_info request; 413f012e29Smrg 423f012e29Smrg memset(&request, 0, sizeof(request)); 433f012e29Smrg request.return_pointer = (uintptr_t)value; 443f012e29Smrg request.return_size = size; 453f012e29Smrg request.query = info_id; 463f012e29Smrg 473f012e29Smrg return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request, 483f012e29Smrg sizeof(struct drm_amdgpu_info)); 493f012e29Smrg} 503f012e29Smrg 513f012e29Smrgint amdgpu_query_crtc_from_id(amdgpu_device_handle dev, unsigned id, 523f012e29Smrg int32_t *result) 533f012e29Smrg{ 543f012e29Smrg struct drm_amdgpu_info request; 553f012e29Smrg 563f012e29Smrg memset(&request, 0, sizeof(request)); 573f012e29Smrg request.return_pointer = (uintptr_t)result; 583f012e29Smrg request.return_size = sizeof(*result); 593f012e29Smrg request.query = AMDGPU_INFO_CRTC_FROM_ID; 603f012e29Smrg request.mode_crtc.id = id; 613f012e29Smrg 623f012e29Smrg return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request, 633f012e29Smrg sizeof(struct drm_amdgpu_info)); 643f012e29Smrg} 653f012e29Smrg 663f012e29Smrgint amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset, 673f012e29Smrg unsigned count, uint32_t instance, uint32_t flags, 683f012e29Smrg uint32_t *values) 693f012e29Smrg{ 703f012e29Smrg struct drm_amdgpu_info request; 713f012e29Smrg 723f012e29Smrg memset(&request, 0, sizeof(request)); 733f012e29Smrg request.return_pointer = (uintptr_t)values; 743f012e29Smrg request.return_size = count * sizeof(uint32_t); 753f012e29Smrg request.query = AMDGPU_INFO_READ_MMR_REG; 763f012e29Smrg request.read_mmr_reg.dword_offset = dword_offset; 773f012e29Smrg request.read_mmr_reg.count = count; 783f012e29Smrg request.read_mmr_reg.instance = instance; 793f012e29Smrg request.read_mmr_reg.flags = flags; 803f012e29Smrg 813f012e29Smrg return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request, 823f012e29Smrg sizeof(struct drm_amdgpu_info)); 833f012e29Smrg} 843f012e29Smrg 853f012e29Smrgint amdgpu_query_hw_ip_count(amdgpu_device_handle dev, unsigned type, 863f012e29Smrg uint32_t *count) 873f012e29Smrg{ 883f012e29Smrg struct drm_amdgpu_info request; 893f012e29Smrg 903f012e29Smrg memset(&request, 0, sizeof(request)); 913f012e29Smrg request.return_pointer = (uintptr_t)count; 923f012e29Smrg request.return_size = sizeof(*count); 933f012e29Smrg request.query = AMDGPU_INFO_HW_IP_COUNT; 943f012e29Smrg request.query_hw_ip.type = type; 953f012e29Smrg 963f012e29Smrg return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request, 973f012e29Smrg sizeof(struct drm_amdgpu_info)); 983f012e29Smrg} 993f012e29Smrg 1003f012e29Smrgint amdgpu_query_hw_ip_info(amdgpu_device_handle dev, unsigned type, 1013f012e29Smrg unsigned ip_instance, 1023f012e29Smrg struct drm_amdgpu_info_hw_ip *info) 1033f012e29Smrg{ 1043f012e29Smrg struct drm_amdgpu_info request; 1053f012e29Smrg 1063f012e29Smrg memset(&request, 0, sizeof(request)); 1073f012e29Smrg request.return_pointer = (uintptr_t)info; 1083f012e29Smrg request.return_size = sizeof(*info); 1093f012e29Smrg request.query = AMDGPU_INFO_HW_IP_INFO; 1103f012e29Smrg request.query_hw_ip.type = type; 1113f012e29Smrg request.query_hw_ip.ip_instance = ip_instance; 1123f012e29Smrg 1133f012e29Smrg return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request, 1143f012e29Smrg sizeof(struct drm_amdgpu_info)); 1153f012e29Smrg} 1163f012e29Smrg 1173f012e29Smrgint amdgpu_query_firmware_version(amdgpu_device_handle dev, unsigned fw_type, 1183f012e29Smrg unsigned ip_instance, unsigned index, 1193f012e29Smrg uint32_t *version, uint32_t *feature) 1203f012e29Smrg{ 1213f012e29Smrg struct drm_amdgpu_info request; 122037b3c26Smrg struct drm_amdgpu_info_firmware firmware = {}; 1233f012e29Smrg int r; 1243f012e29Smrg 1253f012e29Smrg memset(&request, 0, sizeof(request)); 1263f012e29Smrg request.return_pointer = (uintptr_t)&firmware; 1273f012e29Smrg request.return_size = sizeof(firmware); 1283f012e29Smrg request.query = AMDGPU_INFO_FW_VERSION; 1293f012e29Smrg request.query_fw.fw_type = fw_type; 1303f012e29Smrg request.query_fw.ip_instance = ip_instance; 1313f012e29Smrg request.query_fw.index = index; 1323f012e29Smrg 1333f012e29Smrg r = drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request, 1343f012e29Smrg sizeof(struct drm_amdgpu_info)); 1353f012e29Smrg if (r) 1363f012e29Smrg return r; 1373f012e29Smrg 1383f012e29Smrg *version = firmware.ver; 1393f012e29Smrg *feature = firmware.feature; 1403f012e29Smrg return 0; 1413f012e29Smrg} 1423f012e29Smrg 1433f012e29Smrgdrm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev) 1443f012e29Smrg{ 1453f012e29Smrg int r, i; 1463f012e29Smrg 1473f012e29Smrg r = amdgpu_query_info(dev, AMDGPU_INFO_DEV_INFO, sizeof(dev->dev_info), 1483f012e29Smrg &dev->dev_info); 1493f012e29Smrg if (r) 1503f012e29Smrg return r; 1513f012e29Smrg 1523f012e29Smrg dev->info.asic_id = dev->dev_info.device_id; 1533f012e29Smrg dev->info.chip_rev = dev->dev_info.chip_rev; 1543f012e29Smrg dev->info.chip_external_rev = dev->dev_info.external_rev; 1553f012e29Smrg dev->info.family_id = dev->dev_info.family; 1563f012e29Smrg dev->info.max_engine_clk = dev->dev_info.max_engine_clock; 1573f012e29Smrg dev->info.max_memory_clk = dev->dev_info.max_memory_clock; 1583f012e29Smrg dev->info.gpu_counter_freq = dev->dev_info.gpu_counter_freq; 1593f012e29Smrg dev->info.enabled_rb_pipes_mask = dev->dev_info.enabled_rb_pipes_mask; 1603f012e29Smrg dev->info.rb_pipes = dev->dev_info.num_rb_pipes; 1613f012e29Smrg dev->info.ids_flags = dev->dev_info.ids_flags; 1623f012e29Smrg dev->info.num_hw_gfx_contexts = dev->dev_info.num_hw_gfx_contexts; 1633f012e29Smrg dev->info.num_shader_engines = dev->dev_info.num_shader_engines; 1643f012e29Smrg dev->info.num_shader_arrays_per_engine = 1653f012e29Smrg dev->dev_info.num_shader_arrays_per_engine; 1663f012e29Smrg dev->info.vram_type = dev->dev_info.vram_type; 1673f012e29Smrg dev->info.vram_bit_width = dev->dev_info.vram_bit_width; 1683f012e29Smrg dev->info.ce_ram_size = dev->dev_info.ce_ram_size; 1693f012e29Smrg dev->info.vce_harvest_config = dev->dev_info.vce_harvest_config; 1703f012e29Smrg dev->info.pci_rev_id = dev->dev_info.pci_rev; 1713f012e29Smrg 1723f012e29Smrg for (i = 0; i < (int)dev->info.num_shader_engines; i++) { 1733f012e29Smrg unsigned instance = (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) | 1743f012e29Smrg (AMDGPU_INFO_MMR_SH_INDEX_MASK << 1753f012e29Smrg AMDGPU_INFO_MMR_SH_INDEX_SHIFT); 1763f012e29Smrg 1773f012e29Smrg r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0, 1783f012e29Smrg &dev->info.backend_disable[i]); 1793f012e29Smrg if (r) 1803f012e29Smrg return r; 1813f012e29Smrg /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */ 1823f012e29Smrg dev->info.backend_disable[i] = 1833f012e29Smrg (dev->info.backend_disable[i] >> 16) & 0xff; 1843f012e29Smrg 1853f012e29Smrg r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0, 1863f012e29Smrg &dev->info.pa_sc_raster_cfg[i]); 1873f012e29Smrg if (r) 1883f012e29Smrg return r; 1893f012e29Smrg 190037b3c26Smrg if (dev->info.family_id >= AMDGPU_FAMILY_CI) { 191037b3c26Smrg r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0, 1923f012e29Smrg &dev->info.pa_sc_raster_cfg1[i]); 193037b3c26Smrg if (r) 194037b3c26Smrg return r; 195037b3c26Smrg } 1963f012e29Smrg } 1973f012e29Smrg 1983f012e29Smrg r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0, 1993f012e29Smrg dev->info.gb_tile_mode); 2003f012e29Smrg if (r) 2013f012e29Smrg return r; 2023f012e29Smrg 203037b3c26Smrg if (dev->info.family_id >= AMDGPU_FAMILY_CI) { 204037b3c26Smrg r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0, 205037b3c26Smrg dev->info.gb_macro_tile_mode); 206037b3c26Smrg if (r) 207037b3c26Smrg return r; 208037b3c26Smrg } 2093f012e29Smrg 2103f012e29Smrg r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0, 2113f012e29Smrg &dev->info.gb_addr_cfg); 2123f012e29Smrg if (r) 2133f012e29Smrg return r; 2143f012e29Smrg 2153f012e29Smrg r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0, 2163f012e29Smrg &dev->info.mc_arb_ramcfg); 2173f012e29Smrg if (r) 2183f012e29Smrg return r; 2193f012e29Smrg 2203f012e29Smrg dev->info.cu_active_number = dev->dev_info.cu_active_number; 2213f012e29Smrg dev->info.cu_ao_mask = dev->dev_info.cu_ao_mask; 2223f012e29Smrg memcpy(&dev->info.cu_bitmap[0][0], &dev->dev_info.cu_bitmap[0][0], sizeof(dev->info.cu_bitmap)); 2233f012e29Smrg 2243f012e29Smrg /* TODO: info->max_quad_shader_pipes is not set */ 2253f012e29Smrg /* TODO: info->avail_quad_shader_pipes is not set */ 2263f012e29Smrg /* TODO: info->cache_entries_per_quad_pipe is not set */ 2273f012e29Smrg return 0; 2283f012e29Smrg} 2293f012e29Smrg 2303f012e29Smrgint amdgpu_query_gpu_info(amdgpu_device_handle dev, 2313f012e29Smrg struct amdgpu_gpu_info *info) 2323f012e29Smrg{ 233037b3c26Smrg if ((dev == NULL) || (info == NULL)) 234037b3c26Smrg return -EINVAL; 2353f012e29Smrg /* Get ASIC info*/ 2363f012e29Smrg *info = dev->info; 2373f012e29Smrg 2383f012e29Smrg return 0; 2393f012e29Smrg} 2403f012e29Smrg 2413f012e29Smrgint amdgpu_query_heap_info(amdgpu_device_handle dev, 2423f012e29Smrg uint32_t heap, 2433f012e29Smrg uint32_t flags, 2443f012e29Smrg struct amdgpu_heap_info *info) 2453f012e29Smrg{ 2463f012e29Smrg struct drm_amdgpu_info_vram_gtt vram_gtt_info = {}; 2473f012e29Smrg int r; 2483f012e29Smrg 2493f012e29Smrg r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_GTT, 2503f012e29Smrg sizeof(vram_gtt_info), &vram_gtt_info); 2513f012e29Smrg if (r) 2523f012e29Smrg return r; 2533f012e29Smrg 2543f012e29Smrg /* Get heap information */ 2553f012e29Smrg switch (heap) { 2563f012e29Smrg case AMDGPU_GEM_DOMAIN_VRAM: 2573f012e29Smrg /* query visible only vram heap */ 2583f012e29Smrg if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) 2593f012e29Smrg info->heap_size = vram_gtt_info.vram_cpu_accessible_size; 2603f012e29Smrg else /* query total vram heap */ 2613f012e29Smrg info->heap_size = vram_gtt_info.vram_size; 2623f012e29Smrg 2633f012e29Smrg info->max_allocation = vram_gtt_info.vram_cpu_accessible_size; 2643f012e29Smrg 2653f012e29Smrg if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) 2663f012e29Smrg r = amdgpu_query_info(dev, AMDGPU_INFO_VIS_VRAM_USAGE, 2673f012e29Smrg sizeof(info->heap_usage), 2683f012e29Smrg &info->heap_usage); 2693f012e29Smrg else 2703f012e29Smrg r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_USAGE, 2713f012e29Smrg sizeof(info->heap_usage), 2723f012e29Smrg &info->heap_usage); 2733f012e29Smrg if (r) 2743f012e29Smrg return r; 2753f012e29Smrg break; 2763f012e29Smrg case AMDGPU_GEM_DOMAIN_GTT: 2773f012e29Smrg info->heap_size = vram_gtt_info.gtt_size; 2783f012e29Smrg info->max_allocation = vram_gtt_info.vram_cpu_accessible_size; 2793f012e29Smrg 2803f012e29Smrg r = amdgpu_query_info(dev, AMDGPU_INFO_GTT_USAGE, 2813f012e29Smrg sizeof(info->heap_usage), 2823f012e29Smrg &info->heap_usage); 2833f012e29Smrg if (r) 2843f012e29Smrg return r; 2853f012e29Smrg break; 2863f012e29Smrg default: 2873f012e29Smrg return -EINVAL; 2883f012e29Smrg } 2893f012e29Smrg 2903f012e29Smrg return 0; 2913f012e29Smrg} 2923f012e29Smrg 2933f012e29Smrgint amdgpu_query_gds_info(amdgpu_device_handle dev, 2943f012e29Smrg struct amdgpu_gds_resource_info *gds_info) 2953f012e29Smrg{ 2963f012e29Smrg struct drm_amdgpu_info_gds gds_config = {}; 2973f012e29Smrg int r; 2983f012e29Smrg 2993f012e29Smrg if (gds_info == NULL) 3003f012e29Smrg return -EINVAL; 3013f012e29Smrg 3023f012e29Smrg r = amdgpu_query_info(dev, AMDGPU_INFO_GDS_CONFIG, 3033f012e29Smrg sizeof(gds_config), &gds_config); 3043f012e29Smrg if (r) 3053f012e29Smrg return r; 3063f012e29Smrg 3073f012e29Smrg gds_info->gds_gfx_partition_size = gds_config.gds_gfx_partition_size; 3083f012e29Smrg gds_info->compute_partition_size = gds_config.compute_partition_size; 3093f012e29Smrg gds_info->gds_total_size = gds_config.gds_total_size; 3103f012e29Smrg gds_info->gws_per_gfx_partition = gds_config.gws_per_gfx_partition; 3113f012e29Smrg gds_info->gws_per_compute_partition = gds_config.gws_per_compute_partition; 3123f012e29Smrg gds_info->oa_per_gfx_partition = gds_config.oa_per_gfx_partition; 3133f012e29Smrg gds_info->oa_per_compute_partition = gds_config.oa_per_compute_partition; 3143f012e29Smrg 3153f012e29Smrg return 0; 3163f012e29Smrg} 317