amdgpu_gpu_info.c revision d8807b2f
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
172d8807b2fSmrg	if (dev->info.family_id < AMDGPU_FAMILY_AI) {
173d8807b2fSmrg		for (i = 0; i < (int)dev->info.num_shader_engines; i++) {
174d8807b2fSmrg			unsigned instance = (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
175d8807b2fSmrg					    (AMDGPU_INFO_MMR_SH_INDEX_MASK <<
176d8807b2fSmrg					     AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
177d8807b2fSmrg
178d8807b2fSmrg			r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0,
179d8807b2fSmrg						     &dev->info.backend_disable[i]);
180d8807b2fSmrg			if (r)
181d8807b2fSmrg				return r;
182d8807b2fSmrg			/* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */
183d8807b2fSmrg			dev->info.backend_disable[i] =
184d8807b2fSmrg				(dev->info.backend_disable[i] >> 16) & 0xff;
1853f012e29Smrg
186d8807b2fSmrg			r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0,
187d8807b2fSmrg						     &dev->info.pa_sc_raster_cfg[i]);
188037b3c26Smrg			if (r)
189037b3c26Smrg				return r;
190d8807b2fSmrg
191d8807b2fSmrg			if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
192d8807b2fSmrg				r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
193d8807b2fSmrg						     &dev->info.pa_sc_raster_cfg1[i]);
194d8807b2fSmrg				if (r)
195d8807b2fSmrg					return r;
196d8807b2fSmrg			}
197037b3c26Smrg		}
1983f012e29Smrg	}
1993f012e29Smrg
200d8807b2fSmrg	r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
201d8807b2fSmrg					     &dev->info.gb_addr_cfg);
2023f012e29Smrg	if (r)
2033f012e29Smrg		return r;
2043f012e29Smrg
205d8807b2fSmrg	if (dev->info.family_id < AMDGPU_FAMILY_AI) {
206d8807b2fSmrg		r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
207d8807b2fSmrg					     dev->info.gb_tile_mode);
208037b3c26Smrg		if (r)
209037b3c26Smrg			return r;
2103f012e29Smrg
211d8807b2fSmrg		if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
212d8807b2fSmrg			r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
213d8807b2fSmrg						     dev->info.gb_macro_tile_mode);
214d8807b2fSmrg			if (r)
215d8807b2fSmrg				return r;
216d8807b2fSmrg		}
2173f012e29Smrg
218d8807b2fSmrg		r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
219d8807b2fSmrg					     &dev->info.mc_arb_ramcfg);
220d8807b2fSmrg		if (r)
221d8807b2fSmrg			return r;
222d8807b2fSmrg	}
2233f012e29Smrg
2243f012e29Smrg	dev->info.cu_active_number = dev->dev_info.cu_active_number;
2253f012e29Smrg	dev->info.cu_ao_mask = dev->dev_info.cu_ao_mask;
2263f012e29Smrg	memcpy(&dev->info.cu_bitmap[0][0], &dev->dev_info.cu_bitmap[0][0], sizeof(dev->info.cu_bitmap));
2273f012e29Smrg
2283f012e29Smrg	/* TODO: info->max_quad_shader_pipes is not set */
2293f012e29Smrg	/* TODO: info->avail_quad_shader_pipes is not set */
2303f012e29Smrg	/* TODO: info->cache_entries_per_quad_pipe is not set */
2313f012e29Smrg	return 0;
2323f012e29Smrg}
2333f012e29Smrg
2343f012e29Smrgint amdgpu_query_gpu_info(amdgpu_device_handle dev,
2353f012e29Smrg			struct amdgpu_gpu_info *info)
2363f012e29Smrg{
237d8807b2fSmrg	if (!dev || !info)
238037b3c26Smrg		return -EINVAL;
239d8807b2fSmrg
2403f012e29Smrg	/* Get ASIC info*/
2413f012e29Smrg	*info = dev->info;
2423f012e29Smrg
2433f012e29Smrg	return 0;
2443f012e29Smrg}
2453f012e29Smrg
2463f012e29Smrgint amdgpu_query_heap_info(amdgpu_device_handle dev,
2473f012e29Smrg			uint32_t heap,
2483f012e29Smrg			uint32_t flags,
2493f012e29Smrg			struct amdgpu_heap_info *info)
2503f012e29Smrg{
2513f012e29Smrg	struct drm_amdgpu_info_vram_gtt vram_gtt_info = {};
2523f012e29Smrg	int r;
2533f012e29Smrg
2543f012e29Smrg	r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_GTT,
2553f012e29Smrg			      sizeof(vram_gtt_info), &vram_gtt_info);
2563f012e29Smrg	if (r)
2573f012e29Smrg		return r;
2583f012e29Smrg
2593f012e29Smrg	/* Get heap information */
2603f012e29Smrg	switch (heap) {
2613f012e29Smrg	case AMDGPU_GEM_DOMAIN_VRAM:
2623f012e29Smrg		/* query visible only vram heap */
2633f012e29Smrg		if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
2643f012e29Smrg			info->heap_size = vram_gtt_info.vram_cpu_accessible_size;
2653f012e29Smrg		else /* query total vram heap */
2663f012e29Smrg			info->heap_size = vram_gtt_info.vram_size;
2673f012e29Smrg
2683f012e29Smrg		info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
2693f012e29Smrg
2703f012e29Smrg		if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
2713f012e29Smrg			r = amdgpu_query_info(dev, AMDGPU_INFO_VIS_VRAM_USAGE,
2723f012e29Smrg					      sizeof(info->heap_usage),
2733f012e29Smrg					      &info->heap_usage);
2743f012e29Smrg		else
2753f012e29Smrg			r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_USAGE,
2763f012e29Smrg					      sizeof(info->heap_usage),
2773f012e29Smrg					      &info->heap_usage);
2783f012e29Smrg		if (r)
2793f012e29Smrg			return r;
2803f012e29Smrg		break;
2813f012e29Smrg	case AMDGPU_GEM_DOMAIN_GTT:
2823f012e29Smrg		info->heap_size = vram_gtt_info.gtt_size;
2833f012e29Smrg		info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
2843f012e29Smrg
2853f012e29Smrg		r = amdgpu_query_info(dev, AMDGPU_INFO_GTT_USAGE,
2863f012e29Smrg				      sizeof(info->heap_usage),
2873f012e29Smrg				      &info->heap_usage);
2883f012e29Smrg		if (r)
2893f012e29Smrg			return r;
2903f012e29Smrg		break;
2913f012e29Smrg	default:
2923f012e29Smrg		return -EINVAL;
2933f012e29Smrg	}
2943f012e29Smrg
2953f012e29Smrg	return 0;
2963f012e29Smrg}
2973f012e29Smrg
2983f012e29Smrgint amdgpu_query_gds_info(amdgpu_device_handle dev,
2993f012e29Smrg			struct amdgpu_gds_resource_info *gds_info)
3003f012e29Smrg{
3013f012e29Smrg	struct drm_amdgpu_info_gds gds_config = {};
3023f012e29Smrg        int r;
3033f012e29Smrg
304d8807b2fSmrg	if (!gds_info)
3053f012e29Smrg		return -EINVAL;
3063f012e29Smrg
3073f012e29Smrg        r = amdgpu_query_info(dev, AMDGPU_INFO_GDS_CONFIG,
3083f012e29Smrg                              sizeof(gds_config), &gds_config);
3093f012e29Smrg        if (r)
3103f012e29Smrg                return r;
3113f012e29Smrg
3123f012e29Smrg	gds_info->gds_gfx_partition_size = gds_config.gds_gfx_partition_size;
3133f012e29Smrg	gds_info->compute_partition_size = gds_config.compute_partition_size;
3143f012e29Smrg	gds_info->gds_total_size = gds_config.gds_total_size;
3153f012e29Smrg	gds_info->gws_per_gfx_partition = gds_config.gws_per_gfx_partition;
3163f012e29Smrg	gds_info->gws_per_compute_partition = gds_config.gws_per_compute_partition;
3173f012e29Smrg	gds_info->oa_per_gfx_partition = gds_config.oa_per_gfx_partition;
3183f012e29Smrg	gds_info->oa_per_compute_partition = gds_config.oa_per_compute_partition;
3193f012e29Smrg
3203f012e29Smrg	return 0;
3213f012e29Smrg}
322d8807b2fSmrg
323d8807b2fSmrgint amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned sensor_type,
324d8807b2fSmrg			     unsigned size, void *value)
325d8807b2fSmrg{
326d8807b2fSmrg	struct drm_amdgpu_info request;
327d8807b2fSmrg
328d8807b2fSmrg	memset(&request, 0, sizeof(request));
329d8807b2fSmrg	request.return_pointer = (uintptr_t)value;
330d8807b2fSmrg	request.return_size = size;
331d8807b2fSmrg	request.query = AMDGPU_INFO_SENSOR;
332d8807b2fSmrg	request.sensor_info.type = sensor_type;
333d8807b2fSmrg
334d8807b2fSmrg	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
335d8807b2fSmrg			       sizeof(struct drm_amdgpu_info));
336d8807b2fSmrg}
337