amdgpu_gpu_info.c revision 41687f09
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#include <errno.h>
263f012e29Smrg#include <string.h>
273f012e29Smrg
283f012e29Smrg#include "amdgpu.h"
293f012e29Smrg#include "amdgpu_drm.h"
303f012e29Smrg#include "amdgpu_internal.h"
313f012e29Smrg#include "xf86drm.h"
323f012e29Smrg
337cdc0497Smrgdrm_public int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
347cdc0497Smrg				 unsigned size, void *value)
353f012e29Smrg{
363f012e29Smrg	struct drm_amdgpu_info request;
373f012e29Smrg
383f012e29Smrg	memset(&request, 0, sizeof(request));
393f012e29Smrg	request.return_pointer = (uintptr_t)value;
403f012e29Smrg	request.return_size = size;
413f012e29Smrg	request.query = info_id;
423f012e29Smrg
433f012e29Smrg	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
443f012e29Smrg			       sizeof(struct drm_amdgpu_info));
453f012e29Smrg}
463f012e29Smrg
477cdc0497Smrgdrm_public int amdgpu_query_crtc_from_id(amdgpu_device_handle dev, unsigned id,
487cdc0497Smrg					 int32_t *result)
493f012e29Smrg{
503f012e29Smrg	struct drm_amdgpu_info request;
513f012e29Smrg
523f012e29Smrg	memset(&request, 0, sizeof(request));
533f012e29Smrg	request.return_pointer = (uintptr_t)result;
543f012e29Smrg	request.return_size = sizeof(*result);
553f012e29Smrg	request.query = AMDGPU_INFO_CRTC_FROM_ID;
563f012e29Smrg	request.mode_crtc.id = id;
573f012e29Smrg
583f012e29Smrg	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
593f012e29Smrg			       sizeof(struct drm_amdgpu_info));
603f012e29Smrg}
613f012e29Smrg
627cdc0497Smrgdrm_public int amdgpu_read_mm_registers(amdgpu_device_handle dev,
637cdc0497Smrg		unsigned dword_offset, unsigned count, uint32_t instance,
647cdc0497Smrg		uint32_t flags, uint32_t *values)
653f012e29Smrg{
663f012e29Smrg	struct drm_amdgpu_info request;
673f012e29Smrg
683f012e29Smrg	memset(&request, 0, sizeof(request));
693f012e29Smrg	request.return_pointer = (uintptr_t)values;
703f012e29Smrg	request.return_size = count * sizeof(uint32_t);
713f012e29Smrg	request.query = AMDGPU_INFO_READ_MMR_REG;
723f012e29Smrg	request.read_mmr_reg.dword_offset = dword_offset;
733f012e29Smrg	request.read_mmr_reg.count = count;
743f012e29Smrg	request.read_mmr_reg.instance = instance;
753f012e29Smrg	request.read_mmr_reg.flags = flags;
763f012e29Smrg
773f012e29Smrg	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
783f012e29Smrg			       sizeof(struct drm_amdgpu_info));
793f012e29Smrg}
803f012e29Smrg
817cdc0497Smrgdrm_public int amdgpu_query_hw_ip_count(amdgpu_device_handle dev,
827cdc0497Smrg					unsigned type,
837cdc0497Smrg					uint32_t *count)
843f012e29Smrg{
853f012e29Smrg	struct drm_amdgpu_info request;
863f012e29Smrg
873f012e29Smrg	memset(&request, 0, sizeof(request));
883f012e29Smrg	request.return_pointer = (uintptr_t)count;
893f012e29Smrg	request.return_size = sizeof(*count);
903f012e29Smrg	request.query = AMDGPU_INFO_HW_IP_COUNT;
913f012e29Smrg	request.query_hw_ip.type = type;
923f012e29Smrg
933f012e29Smrg	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
943f012e29Smrg			       sizeof(struct drm_amdgpu_info));
953f012e29Smrg}
963f012e29Smrg
977cdc0497Smrgdrm_public int amdgpu_query_hw_ip_info(amdgpu_device_handle dev, unsigned type,
987cdc0497Smrg				       unsigned ip_instance,
997cdc0497Smrg				       struct drm_amdgpu_info_hw_ip *info)
1003f012e29Smrg{
1013f012e29Smrg	struct drm_amdgpu_info request;
1023f012e29Smrg
1033f012e29Smrg	memset(&request, 0, sizeof(request));
1043f012e29Smrg	request.return_pointer = (uintptr_t)info;
1053f012e29Smrg	request.return_size = sizeof(*info);
1063f012e29Smrg	request.query = AMDGPU_INFO_HW_IP_INFO;
1073f012e29Smrg	request.query_hw_ip.type = type;
1083f012e29Smrg	request.query_hw_ip.ip_instance = ip_instance;
1093f012e29Smrg
1103f012e29Smrg	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
1113f012e29Smrg			       sizeof(struct drm_amdgpu_info));
1123f012e29Smrg}
1133f012e29Smrg
1147cdc0497Smrgdrm_public int amdgpu_query_firmware_version(amdgpu_device_handle dev,
1157cdc0497Smrg		unsigned fw_type, unsigned ip_instance, unsigned index,
1167cdc0497Smrg		uint32_t *version, uint32_t *feature)
1173f012e29Smrg{
1183f012e29Smrg	struct drm_amdgpu_info request;
119037b3c26Smrg	struct drm_amdgpu_info_firmware firmware = {};
1203f012e29Smrg	int r;
1213f012e29Smrg
1223f012e29Smrg	memset(&request, 0, sizeof(request));
1233f012e29Smrg	request.return_pointer = (uintptr_t)&firmware;
1243f012e29Smrg	request.return_size = sizeof(firmware);
1253f012e29Smrg	request.query = AMDGPU_INFO_FW_VERSION;
1263f012e29Smrg	request.query_fw.fw_type = fw_type;
1273f012e29Smrg	request.query_fw.ip_instance = ip_instance;
1283f012e29Smrg	request.query_fw.index = index;
1293f012e29Smrg
1303f012e29Smrg	r = drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
1313f012e29Smrg			    sizeof(struct drm_amdgpu_info));
1323f012e29Smrg	if (r)
1333f012e29Smrg		return r;
1343f012e29Smrg
1353f012e29Smrg	*version = firmware.ver;
1363f012e29Smrg	*feature = firmware.feature;
1373f012e29Smrg	return 0;
1383f012e29Smrg}
1393f012e29Smrg
1403f012e29Smrgdrm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev)
1413f012e29Smrg{
1423f012e29Smrg	int r, i;
1433f012e29Smrg
1443f012e29Smrg	r = amdgpu_query_info(dev, AMDGPU_INFO_DEV_INFO, sizeof(dev->dev_info),
1453f012e29Smrg			      &dev->dev_info);
1463f012e29Smrg	if (r)
1473f012e29Smrg		return r;
1483f012e29Smrg
1493f012e29Smrg	dev->info.asic_id = dev->dev_info.device_id;
1503f012e29Smrg	dev->info.chip_rev = dev->dev_info.chip_rev;
1513f012e29Smrg	dev->info.chip_external_rev = dev->dev_info.external_rev;
1523f012e29Smrg	dev->info.family_id = dev->dev_info.family;
1533f012e29Smrg	dev->info.max_engine_clk = dev->dev_info.max_engine_clock;
1543f012e29Smrg	dev->info.max_memory_clk = dev->dev_info.max_memory_clock;
1553f012e29Smrg	dev->info.gpu_counter_freq = dev->dev_info.gpu_counter_freq;
1563f012e29Smrg	dev->info.enabled_rb_pipes_mask = dev->dev_info.enabled_rb_pipes_mask;
1573f012e29Smrg	dev->info.rb_pipes = dev->dev_info.num_rb_pipes;
1583f012e29Smrg	dev->info.ids_flags = dev->dev_info.ids_flags;
1593f012e29Smrg	dev->info.num_hw_gfx_contexts = dev->dev_info.num_hw_gfx_contexts;
1603f012e29Smrg	dev->info.num_shader_engines = dev->dev_info.num_shader_engines;
1613f012e29Smrg	dev->info.num_shader_arrays_per_engine =
1623f012e29Smrg		dev->dev_info.num_shader_arrays_per_engine;
1633f012e29Smrg	dev->info.vram_type = dev->dev_info.vram_type;
1643f012e29Smrg	dev->info.vram_bit_width = dev->dev_info.vram_bit_width;
1653f012e29Smrg	dev->info.ce_ram_size = dev->dev_info.ce_ram_size;
1663f012e29Smrg	dev->info.vce_harvest_config = dev->dev_info.vce_harvest_config;
1673f012e29Smrg	dev->info.pci_rev_id = dev->dev_info.pci_rev;
1683f012e29Smrg
169d8807b2fSmrg	if (dev->info.family_id < AMDGPU_FAMILY_AI) {
170d8807b2fSmrg		for (i = 0; i < (int)dev->info.num_shader_engines; i++) {
171d8807b2fSmrg			unsigned instance = (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
172d8807b2fSmrg					    (AMDGPU_INFO_MMR_SH_INDEX_MASK <<
173d8807b2fSmrg					     AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
174d8807b2fSmrg
175d8807b2fSmrg			r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0,
176d8807b2fSmrg						     &dev->info.backend_disable[i]);
177d8807b2fSmrg			if (r)
178d8807b2fSmrg				return r;
179d8807b2fSmrg			/* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */
180d8807b2fSmrg			dev->info.backend_disable[i] =
181d8807b2fSmrg				(dev->info.backend_disable[i] >> 16) & 0xff;
1823f012e29Smrg
183d8807b2fSmrg			r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0,
184d8807b2fSmrg						     &dev->info.pa_sc_raster_cfg[i]);
185037b3c26Smrg			if (r)
186037b3c26Smrg				return r;
187d8807b2fSmrg
188d8807b2fSmrg			if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
189d8807b2fSmrg				r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
190d8807b2fSmrg						     &dev->info.pa_sc_raster_cfg1[i]);
191d8807b2fSmrg				if (r)
192d8807b2fSmrg					return r;
193d8807b2fSmrg			}
194037b3c26Smrg		}
1953f012e29Smrg	}
1963f012e29Smrg
197d8807b2fSmrg	r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
198d8807b2fSmrg					     &dev->info.gb_addr_cfg);
1993f012e29Smrg	if (r)
2003f012e29Smrg		return r;
2013f012e29Smrg
202d8807b2fSmrg	if (dev->info.family_id < AMDGPU_FAMILY_AI) {
203d8807b2fSmrg		r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
204d8807b2fSmrg					     dev->info.gb_tile_mode);
205037b3c26Smrg		if (r)
206037b3c26Smrg			return r;
2073f012e29Smrg
208d8807b2fSmrg		if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
209d8807b2fSmrg			r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
210d8807b2fSmrg						     dev->info.gb_macro_tile_mode);
211d8807b2fSmrg			if (r)
212d8807b2fSmrg				return r;
213d8807b2fSmrg		}
2143f012e29Smrg
215d8807b2fSmrg		r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
216d8807b2fSmrg					     &dev->info.mc_arb_ramcfg);
217d8807b2fSmrg		if (r)
218d8807b2fSmrg			return r;
219d8807b2fSmrg	}
2203f012e29Smrg
2213f012e29Smrg	dev->info.cu_active_number = dev->dev_info.cu_active_number;
2223f012e29Smrg	dev->info.cu_ao_mask = dev->dev_info.cu_ao_mask;
2233f012e29Smrg	memcpy(&dev->info.cu_bitmap[0][0], &dev->dev_info.cu_bitmap[0][0], sizeof(dev->info.cu_bitmap));
2243f012e29Smrg
2253f012e29Smrg	/* TODO: info->max_quad_shader_pipes is not set */
2263f012e29Smrg	/* TODO: info->avail_quad_shader_pipes is not set */
2273f012e29Smrg	/* TODO: info->cache_entries_per_quad_pipe is not set */
2283f012e29Smrg	return 0;
2293f012e29Smrg}
2303f012e29Smrg
2317cdc0497Smrgdrm_public int amdgpu_query_gpu_info(amdgpu_device_handle dev,
2327cdc0497Smrg				     struct amdgpu_gpu_info *info)
2333f012e29Smrg{
234d8807b2fSmrg	if (!dev || !info)
235037b3c26Smrg		return -EINVAL;
236d8807b2fSmrg
2373f012e29Smrg	/* Get ASIC info*/
2383f012e29Smrg	*info = dev->info;
2393f012e29Smrg
2403f012e29Smrg	return 0;
2413f012e29Smrg}
2423f012e29Smrg
2437cdc0497Smrgdrm_public int amdgpu_query_heap_info(amdgpu_device_handle dev,
2447cdc0497Smrg				      uint32_t heap,
2457cdc0497Smrg				      uint32_t flags,
2467cdc0497Smrg				      struct amdgpu_heap_info *info)
2473f012e29Smrg{
2483f012e29Smrg	struct drm_amdgpu_info_vram_gtt vram_gtt_info = {};
2493f012e29Smrg	int r;
2503f012e29Smrg
2513f012e29Smrg	r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_GTT,
2523f012e29Smrg			      sizeof(vram_gtt_info), &vram_gtt_info);
2533f012e29Smrg	if (r)
2543f012e29Smrg		return r;
2553f012e29Smrg
2563f012e29Smrg	/* Get heap information */
2573f012e29Smrg	switch (heap) {
2583f012e29Smrg	case AMDGPU_GEM_DOMAIN_VRAM:
2593f012e29Smrg		/* query visible only vram heap */
2603f012e29Smrg		if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
2613f012e29Smrg			info->heap_size = vram_gtt_info.vram_cpu_accessible_size;
2623f012e29Smrg		else /* query total vram heap */
2633f012e29Smrg			info->heap_size = vram_gtt_info.vram_size;
2643f012e29Smrg
2653f012e29Smrg		info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
2663f012e29Smrg
2673f012e29Smrg		if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
2683f012e29Smrg			r = amdgpu_query_info(dev, AMDGPU_INFO_VIS_VRAM_USAGE,
2693f012e29Smrg					      sizeof(info->heap_usage),
2703f012e29Smrg					      &info->heap_usage);
2713f012e29Smrg		else
2723f012e29Smrg			r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_USAGE,
2733f012e29Smrg					      sizeof(info->heap_usage),
2743f012e29Smrg					      &info->heap_usage);
2753f012e29Smrg		if (r)
2763f012e29Smrg			return r;
2773f012e29Smrg		break;
2783f012e29Smrg	case AMDGPU_GEM_DOMAIN_GTT:
2793f012e29Smrg		info->heap_size = vram_gtt_info.gtt_size;
2803f012e29Smrg		info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
2813f012e29Smrg
2823f012e29Smrg		r = amdgpu_query_info(dev, AMDGPU_INFO_GTT_USAGE,
2833f012e29Smrg				      sizeof(info->heap_usage),
2843f012e29Smrg				      &info->heap_usage);
2853f012e29Smrg		if (r)
2863f012e29Smrg			return r;
2873f012e29Smrg		break;
2883f012e29Smrg	default:
2893f012e29Smrg		return -EINVAL;
2903f012e29Smrg	}
2913f012e29Smrg
2923f012e29Smrg	return 0;
2933f012e29Smrg}
2943f012e29Smrg
2957cdc0497Smrgdrm_public int amdgpu_query_gds_info(amdgpu_device_handle dev,
2967cdc0497Smrg				     struct amdgpu_gds_resource_info *gds_info)
2973f012e29Smrg{
2983f012e29Smrg	struct drm_amdgpu_info_gds gds_config = {};
2993f012e29Smrg        int r;
3003f012e29Smrg
301d8807b2fSmrg	if (!gds_info)
3023f012e29Smrg		return -EINVAL;
3033f012e29Smrg
3043f012e29Smrg        r = amdgpu_query_info(dev, AMDGPU_INFO_GDS_CONFIG,
3053f012e29Smrg                              sizeof(gds_config), &gds_config);
3063f012e29Smrg        if (r)
3073f012e29Smrg                return r;
3083f012e29Smrg
3093f012e29Smrg	gds_info->gds_gfx_partition_size = gds_config.gds_gfx_partition_size;
3103f012e29Smrg	gds_info->compute_partition_size = gds_config.compute_partition_size;
3113f012e29Smrg	gds_info->gds_total_size = gds_config.gds_total_size;
3123f012e29Smrg	gds_info->gws_per_gfx_partition = gds_config.gws_per_gfx_partition;
3133f012e29Smrg	gds_info->gws_per_compute_partition = gds_config.gws_per_compute_partition;
3143f012e29Smrg	gds_info->oa_per_gfx_partition = gds_config.oa_per_gfx_partition;
3153f012e29Smrg	gds_info->oa_per_compute_partition = gds_config.oa_per_compute_partition;
3163f012e29Smrg
3173f012e29Smrg	return 0;
3183f012e29Smrg}
319d8807b2fSmrg
3207cdc0497Smrgdrm_public int amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned sensor_type,
3217cdc0497Smrg					unsigned size, void *value)
322d8807b2fSmrg{
323d8807b2fSmrg	struct drm_amdgpu_info request;
324d8807b2fSmrg
325d8807b2fSmrg	memset(&request, 0, sizeof(request));
326d8807b2fSmrg	request.return_pointer = (uintptr_t)value;
327d8807b2fSmrg	request.return_size = size;
328d8807b2fSmrg	request.query = AMDGPU_INFO_SENSOR;
329d8807b2fSmrg	request.sensor_info.type = sensor_type;
330d8807b2fSmrg
331d8807b2fSmrg	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
332d8807b2fSmrg			       sizeof(struct drm_amdgpu_info));
333d8807b2fSmrg}
33441687f09Smrg
33541687f09Smrgdrm_public int amdgpu_query_video_caps_info(amdgpu_device_handle dev, unsigned cap_type,
33641687f09Smrg                                            unsigned size, void *value)
33741687f09Smrg{
33841687f09Smrg	struct drm_amdgpu_info request;
33941687f09Smrg
34041687f09Smrg	memset(&request, 0, sizeof(request));
34141687f09Smrg	request.return_pointer = (uintptr_t)value;
34241687f09Smrg	request.return_size = size;
34341687f09Smrg	request.query = AMDGPU_INFO_VIDEO_CAPS;
34441687f09Smrg	request.sensor_info.type = cap_type;
34541687f09Smrg
34641687f09Smrg	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
34741687f09Smrg			       sizeof(struct drm_amdgpu_info));
34841687f09Smrg}
349