amdgpu_gpu_info.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /*
  2. * Copyright © 2014 Advanced Micro Devices, Inc.
  3. * All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21. * OTHER DEALINGS IN THE SOFTWARE.
  22. *
  23. */
  24. #include <errno.h>
  25. #include <string.h>
  26. #include "amdgpu.h"
  27. #include "amdgpu_drm.h"
  28. #include "amdgpu_internal.h"
  29. #include "util_math.h"
  30. #include "xf86drm.h"
  31. #ifndef ARRAY_SIZE
  32. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  33. #endif
  34. drm_public int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
  35. unsigned size, void *value)
  36. {
  37. struct drm_amdgpu_info request;
  38. memset(&request, 0, sizeof(request));
  39. request.return_pointer = (uintptr_t)value;
  40. request.return_size = size;
  41. request.query = info_id;
  42. return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  43. sizeof(struct drm_amdgpu_info));
  44. }
  45. drm_public int amdgpu_query_crtc_from_id(amdgpu_device_handle dev, unsigned id,
  46. int32_t *result)
  47. {
  48. struct drm_amdgpu_info request;
  49. memset(&request, 0, sizeof(request));
  50. request.return_pointer = (uintptr_t)result;
  51. request.return_size = sizeof(*result);
  52. request.query = AMDGPU_INFO_CRTC_FROM_ID;
  53. request.mode_crtc.id = id;
  54. return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  55. sizeof(struct drm_amdgpu_info));
  56. }
  57. drm_public int amdgpu_read_mm_registers(amdgpu_device_handle dev,
  58. unsigned dword_offset, unsigned count, uint32_t instance,
  59. uint32_t flags, uint32_t *values)
  60. {
  61. struct drm_amdgpu_info request;
  62. memset(&request, 0, sizeof(request));
  63. request.return_pointer = (uintptr_t)values;
  64. request.return_size = count * sizeof(uint32_t);
  65. request.query = AMDGPU_INFO_READ_MMR_REG;
  66. request.read_mmr_reg.dword_offset = dword_offset;
  67. request.read_mmr_reg.count = count;
  68. request.read_mmr_reg.instance = instance;
  69. request.read_mmr_reg.flags = flags;
  70. return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  71. sizeof(struct drm_amdgpu_info));
  72. }
  73. drm_public int amdgpu_query_hw_ip_count(amdgpu_device_handle dev,
  74. unsigned type,
  75. uint32_t *count)
  76. {
  77. struct drm_amdgpu_info request;
  78. memset(&request, 0, sizeof(request));
  79. request.return_pointer = (uintptr_t)count;
  80. request.return_size = sizeof(*count);
  81. request.query = AMDGPU_INFO_HW_IP_COUNT;
  82. request.query_hw_ip.type = type;
  83. return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  84. sizeof(struct drm_amdgpu_info));
  85. }
  86. drm_public int amdgpu_query_hw_ip_info(amdgpu_device_handle dev, unsigned type,
  87. unsigned ip_instance,
  88. struct drm_amdgpu_info_hw_ip *info)
  89. {
  90. struct drm_amdgpu_info request;
  91. memset(&request, 0, sizeof(request));
  92. request.return_pointer = (uintptr_t)info;
  93. request.return_size = sizeof(*info);
  94. request.query = AMDGPU_INFO_HW_IP_INFO;
  95. request.query_hw_ip.type = type;
  96. request.query_hw_ip.ip_instance = ip_instance;
  97. return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  98. sizeof(struct drm_amdgpu_info));
  99. }
  100. drm_public int amdgpu_query_firmware_version(amdgpu_device_handle dev,
  101. unsigned fw_type, unsigned ip_instance, unsigned index,
  102. uint32_t *version, uint32_t *feature)
  103. {
  104. struct drm_amdgpu_info request;
  105. struct drm_amdgpu_info_firmware firmware = {};
  106. int r;
  107. memset(&request, 0, sizeof(request));
  108. request.return_pointer = (uintptr_t)&firmware;
  109. request.return_size = sizeof(firmware);
  110. request.query = AMDGPU_INFO_FW_VERSION;
  111. request.query_fw.fw_type = fw_type;
  112. request.query_fw.ip_instance = ip_instance;
  113. request.query_fw.index = index;
  114. r = drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  115. sizeof(struct drm_amdgpu_info));
  116. if (r)
  117. return r;
  118. *version = firmware.ver;
  119. *feature = firmware.feature;
  120. return 0;
  121. }
  122. drm_public int amdgpu_query_uq_fw_area_info(amdgpu_device_handle dev,
  123. unsigned type,
  124. unsigned ip_instance,
  125. struct drm_amdgpu_info_uq_fw_areas *info)
  126. {
  127. struct drm_amdgpu_info request;
  128. memset(&request, 0, sizeof(request));
  129. request.return_pointer = (uintptr_t)info;
  130. request.return_size = sizeof(*info);
  131. request.query = AMDGPU_INFO_UQ_FW_AREAS;
  132. request.query_hw_ip.type = type;
  133. request.query_hw_ip.ip_instance = ip_instance;
  134. return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  135. sizeof(struct drm_amdgpu_info));
  136. }
  137. drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev)
  138. {
  139. int r, i;
  140. r = amdgpu_query_info(dev, AMDGPU_INFO_DEV_INFO, sizeof(dev->dev_info),
  141. &dev->dev_info);
  142. if (r)
  143. return r;
  144. dev->info.asic_id = dev->dev_info.device_id;
  145. dev->info.chip_rev = dev->dev_info.chip_rev;
  146. dev->info.chip_external_rev = dev->dev_info.external_rev;
  147. dev->info.family_id = dev->dev_info.family;
  148. dev->info.max_engine_clk = dev->dev_info.max_engine_clock;
  149. dev->info.max_memory_clk = dev->dev_info.max_memory_clock;
  150. dev->info.gpu_counter_freq = dev->dev_info.gpu_counter_freq;
  151. dev->info.enabled_rb_pipes_mask = dev->dev_info.enabled_rb_pipes_mask;
  152. dev->info.rb_pipes = dev->dev_info.num_rb_pipes;
  153. dev->info.ids_flags = dev->dev_info.ids_flags;
  154. dev->info.num_hw_gfx_contexts = dev->dev_info.num_hw_gfx_contexts;
  155. dev->info.num_shader_engines = dev->dev_info.num_shader_engines;
  156. dev->info.num_shader_arrays_per_engine =
  157. dev->dev_info.num_shader_arrays_per_engine;
  158. dev->info.vram_type = dev->dev_info.vram_type;
  159. dev->info.vram_bit_width = dev->dev_info.vram_bit_width;
  160. dev->info.ce_ram_size = dev->dev_info.ce_ram_size;
  161. dev->info.vce_harvest_config = dev->dev_info.vce_harvest_config;
  162. dev->info.pci_rev_id = dev->dev_info.pci_rev;
  163. if (dev->info.family_id < AMDGPU_FAMILY_AI) {
  164. unsigned nse = MIN2(dev->info.num_shader_engines,
  165. ARRAY_SIZE(dev->info.backend_disable));
  166. for (i = 0; i < (int)nse; i++) {
  167. unsigned instance = (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
  168. (AMDGPU_INFO_MMR_SH_INDEX_MASK <<
  169. AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
  170. r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0,
  171. &dev->info.backend_disable[i]);
  172. if (r)
  173. return r;
  174. /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */
  175. dev->info.backend_disable[i] =
  176. (dev->info.backend_disable[i] >> 16) & 0xff;
  177. r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0,
  178. &dev->info.pa_sc_raster_cfg[i]);
  179. if (r)
  180. return r;
  181. if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
  182. r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
  183. &dev->info.pa_sc_raster_cfg1[i]);
  184. if (r)
  185. return r;
  186. }
  187. }
  188. }
  189. r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
  190. &dev->info.gb_addr_cfg);
  191. if (r)
  192. return r;
  193. if (dev->info.family_id < AMDGPU_FAMILY_AI) {
  194. r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
  195. dev->info.gb_tile_mode);
  196. if (r)
  197. return r;
  198. if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
  199. r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
  200. dev->info.gb_macro_tile_mode);
  201. if (r)
  202. return r;
  203. }
  204. r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
  205. &dev->info.mc_arb_ramcfg);
  206. if (r)
  207. return r;
  208. }
  209. dev->info.cu_active_number = dev->dev_info.cu_active_number;
  210. dev->info.cu_ao_mask = dev->dev_info.cu_ao_mask;
  211. memcpy(&dev->info.cu_bitmap[0][0], &dev->dev_info.cu_bitmap[0][0], sizeof(dev->info.cu_bitmap));
  212. /* TODO: info->max_quad_shader_pipes is not set */
  213. /* TODO: info->avail_quad_shader_pipes is not set */
  214. /* TODO: info->cache_entries_per_quad_pipe is not set */
  215. return 0;
  216. }
  217. drm_public int amdgpu_query_gpu_info(amdgpu_device_handle dev,
  218. struct amdgpu_gpu_info *info)
  219. {
  220. if (!dev || !info)
  221. return -EINVAL;
  222. /* Get ASIC info*/
  223. *info = dev->info;
  224. return 0;
  225. }
  226. drm_public int amdgpu_query_heap_info(amdgpu_device_handle dev,
  227. uint32_t heap,
  228. uint32_t flags,
  229. struct amdgpu_heap_info *info)
  230. {
  231. struct drm_amdgpu_info_vram_gtt vram_gtt_info = {};
  232. int r;
  233. r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_GTT,
  234. sizeof(vram_gtt_info), &vram_gtt_info);
  235. if (r)
  236. return r;
  237. /* Get heap information */
  238. switch (heap) {
  239. case AMDGPU_GEM_DOMAIN_VRAM:
  240. /* query visible only vram heap */
  241. if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
  242. info->heap_size = vram_gtt_info.vram_cpu_accessible_size;
  243. else /* query total vram heap */
  244. info->heap_size = vram_gtt_info.vram_size;
  245. info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
  246. if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
  247. r = amdgpu_query_info(dev, AMDGPU_INFO_VIS_VRAM_USAGE,
  248. sizeof(info->heap_usage),
  249. &info->heap_usage);
  250. else
  251. r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_USAGE,
  252. sizeof(info->heap_usage),
  253. &info->heap_usage);
  254. if (r)
  255. return r;
  256. break;
  257. case AMDGPU_GEM_DOMAIN_GTT:
  258. info->heap_size = vram_gtt_info.gtt_size;
  259. info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
  260. r = amdgpu_query_info(dev, AMDGPU_INFO_GTT_USAGE,
  261. sizeof(info->heap_usage),
  262. &info->heap_usage);
  263. if (r)
  264. return r;
  265. break;
  266. default:
  267. return -EINVAL;
  268. }
  269. return 0;
  270. }
  271. drm_public int amdgpu_query_gds_info(amdgpu_device_handle dev,
  272. struct amdgpu_gds_resource_info *gds_info)
  273. {
  274. struct drm_amdgpu_info_gds gds_config = {};
  275. int r;
  276. if (!gds_info)
  277. return -EINVAL;
  278. r = amdgpu_query_info(dev, AMDGPU_INFO_GDS_CONFIG,
  279. sizeof(gds_config), &gds_config);
  280. if (r)
  281. return r;
  282. gds_info->gds_gfx_partition_size = gds_config.gds_gfx_partition_size;
  283. gds_info->compute_partition_size = gds_config.compute_partition_size;
  284. gds_info->gds_total_size = gds_config.gds_total_size;
  285. gds_info->gws_per_gfx_partition = gds_config.gws_per_gfx_partition;
  286. gds_info->gws_per_compute_partition = gds_config.gws_per_compute_partition;
  287. gds_info->oa_per_gfx_partition = gds_config.oa_per_gfx_partition;
  288. gds_info->oa_per_compute_partition = gds_config.oa_per_compute_partition;
  289. return 0;
  290. }
  291. drm_public int amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned sensor_type,
  292. unsigned size, void *value)
  293. {
  294. struct drm_amdgpu_info request;
  295. memset(&request, 0, sizeof(request));
  296. request.return_pointer = (uintptr_t)value;
  297. request.return_size = size;
  298. request.query = AMDGPU_INFO_SENSOR;
  299. request.sensor_info.type = sensor_type;
  300. return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  301. sizeof(struct drm_amdgpu_info));
  302. }
  303. drm_public int amdgpu_query_video_caps_info(amdgpu_device_handle dev, unsigned cap_type,
  304. unsigned size, void *value)
  305. {
  306. struct drm_amdgpu_info request;
  307. memset(&request, 0, sizeof(request));
  308. request.return_pointer = (uintptr_t)value;
  309. request.return_size = size;
  310. request.query = AMDGPU_INFO_VIDEO_CAPS;
  311. request.sensor_info.type = cap_type;
  312. return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  313. sizeof(struct drm_amdgpu_info));
  314. }
  315. drm_public int amdgpu_query_gpuvm_fault_info(amdgpu_device_handle dev,
  316. unsigned size, void *value)
  317. {
  318. struct drm_amdgpu_info request;
  319. memset(&request, 0, sizeof(request));
  320. request.return_pointer = (uintptr_t)value;
  321. request.return_size = size;
  322. request.query = AMDGPU_INFO_GPUVM_FAULT;
  323. return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
  324. sizeof(struct drm_amdgpu_info));
  325. }