amdgpu_gpu_info.c revision 3f012e29
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;
1223f012e29Smrg	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
1903f012e29Smrg		r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
1913f012e29Smrg					     &dev->info.pa_sc_raster_cfg1[i]);
1923f012e29Smrg		if (r)
1933f012e29Smrg			return r;
1943f012e29Smrg	}
1953f012e29Smrg
1963f012e29Smrg	r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
1973f012e29Smrg				     dev->info.gb_tile_mode);
1983f012e29Smrg	if (r)
1993f012e29Smrg		return r;
2003f012e29Smrg
2013f012e29Smrg	r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
2023f012e29Smrg				     dev->info.gb_macro_tile_mode);
2033f012e29Smrg	if (r)
2043f012e29Smrg		return r;
2053f012e29Smrg
2063f012e29Smrg	r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
2073f012e29Smrg				     &dev->info.gb_addr_cfg);
2083f012e29Smrg	if (r)
2093f012e29Smrg		return r;
2103f012e29Smrg
2113f012e29Smrg	r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
2123f012e29Smrg				     &dev->info.mc_arb_ramcfg);
2133f012e29Smrg	if (r)
2143f012e29Smrg		return r;
2153f012e29Smrg
2163f012e29Smrg	dev->info.cu_active_number = dev->dev_info.cu_active_number;
2173f012e29Smrg	dev->info.cu_ao_mask = dev->dev_info.cu_ao_mask;
2183f012e29Smrg	memcpy(&dev->info.cu_bitmap[0][0], &dev->dev_info.cu_bitmap[0][0], sizeof(dev->info.cu_bitmap));
2193f012e29Smrg
2203f012e29Smrg	/* TODO: info->max_quad_shader_pipes is not set */
2213f012e29Smrg	/* TODO: info->avail_quad_shader_pipes is not set */
2223f012e29Smrg	/* TODO: info->cache_entries_per_quad_pipe is not set */
2233f012e29Smrg	return 0;
2243f012e29Smrg}
2253f012e29Smrg
2263f012e29Smrgint amdgpu_query_gpu_info(amdgpu_device_handle dev,
2273f012e29Smrg			struct amdgpu_gpu_info *info)
2283f012e29Smrg{
2293f012e29Smrg	/* Get ASIC info*/
2303f012e29Smrg	*info = dev->info;
2313f012e29Smrg
2323f012e29Smrg	return 0;
2333f012e29Smrg}
2343f012e29Smrg
2353f012e29Smrgint amdgpu_query_heap_info(amdgpu_device_handle dev,
2363f012e29Smrg			uint32_t heap,
2373f012e29Smrg			uint32_t flags,
2383f012e29Smrg			struct amdgpu_heap_info *info)
2393f012e29Smrg{
2403f012e29Smrg	struct drm_amdgpu_info_vram_gtt vram_gtt_info = {};
2413f012e29Smrg	int r;
2423f012e29Smrg
2433f012e29Smrg	r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_GTT,
2443f012e29Smrg			      sizeof(vram_gtt_info), &vram_gtt_info);
2453f012e29Smrg	if (r)
2463f012e29Smrg		return r;
2473f012e29Smrg
2483f012e29Smrg	/* Get heap information */
2493f012e29Smrg	switch (heap) {
2503f012e29Smrg	case AMDGPU_GEM_DOMAIN_VRAM:
2513f012e29Smrg		/* query visible only vram heap */
2523f012e29Smrg		if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
2533f012e29Smrg			info->heap_size = vram_gtt_info.vram_cpu_accessible_size;
2543f012e29Smrg		else /* query total vram heap */
2553f012e29Smrg			info->heap_size = vram_gtt_info.vram_size;
2563f012e29Smrg
2573f012e29Smrg		info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
2583f012e29Smrg
2593f012e29Smrg		if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
2603f012e29Smrg			r = amdgpu_query_info(dev, AMDGPU_INFO_VIS_VRAM_USAGE,
2613f012e29Smrg					      sizeof(info->heap_usage),
2623f012e29Smrg					      &info->heap_usage);
2633f012e29Smrg		else
2643f012e29Smrg			r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_USAGE,
2653f012e29Smrg					      sizeof(info->heap_usage),
2663f012e29Smrg					      &info->heap_usage);
2673f012e29Smrg		if (r)
2683f012e29Smrg			return r;
2693f012e29Smrg		break;
2703f012e29Smrg	case AMDGPU_GEM_DOMAIN_GTT:
2713f012e29Smrg		info->heap_size = vram_gtt_info.gtt_size;
2723f012e29Smrg		info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
2733f012e29Smrg
2743f012e29Smrg		r = amdgpu_query_info(dev, AMDGPU_INFO_GTT_USAGE,
2753f012e29Smrg				      sizeof(info->heap_usage),
2763f012e29Smrg				      &info->heap_usage);
2773f012e29Smrg		if (r)
2783f012e29Smrg			return r;
2793f012e29Smrg		break;
2803f012e29Smrg	default:
2813f012e29Smrg		return -EINVAL;
2823f012e29Smrg	}
2833f012e29Smrg
2843f012e29Smrg	return 0;
2853f012e29Smrg}
2863f012e29Smrg
2873f012e29Smrgint amdgpu_query_gds_info(amdgpu_device_handle dev,
2883f012e29Smrg			struct amdgpu_gds_resource_info *gds_info)
2893f012e29Smrg{
2903f012e29Smrg	struct drm_amdgpu_info_gds gds_config = {};
2913f012e29Smrg        int r;
2923f012e29Smrg
2933f012e29Smrg	if (gds_info == NULL)
2943f012e29Smrg		return -EINVAL;
2953f012e29Smrg
2963f012e29Smrg        r = amdgpu_query_info(dev, AMDGPU_INFO_GDS_CONFIG,
2973f012e29Smrg                              sizeof(gds_config), &gds_config);
2983f012e29Smrg        if (r)
2993f012e29Smrg                return r;
3003f012e29Smrg
3013f012e29Smrg	gds_info->gds_gfx_partition_size = gds_config.gds_gfx_partition_size;
3023f012e29Smrg	gds_info->compute_partition_size = gds_config.compute_partition_size;
3033f012e29Smrg	gds_info->gds_total_size = gds_config.gds_total_size;
3043f012e29Smrg	gds_info->gws_per_gfx_partition = gds_config.gws_per_gfx_partition;
3053f012e29Smrg	gds_info->gws_per_compute_partition = gds_config.gws_per_compute_partition;
3063f012e29Smrg	gds_info->oa_per_gfx_partition = gds_config.oa_per_gfx_partition;
3073f012e29Smrg	gds_info->oa_per_compute_partition = gds_config.oa_per_compute_partition;
3083f012e29Smrg
3093f012e29Smrg	return 0;
3103f012e29Smrg}
311