1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
/*
Copyright (C) 2012 Lauri Kasanen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "radeontop.h"
#include <xf86drm.h>
#include <libdrm/amdgpu_drm.h>
#include <libdrm/amdgpu.h>
static amdgpu_device_handle amdgpu_dev;
static int getgrbm_amdgpu(uint32_t *out) {
return amdgpu_read_mm_registers(amdgpu_dev, GRBM_STATUS / 4, 1,
0xffffffff, 0, out);
}
static int getvram_amdgpu(uint64_t *out) {
return amdgpu_query_info(amdgpu_dev, AMDGPU_INFO_VRAM_USAGE,
sizeof(uint64_t), out);
}
static int getgtt_amdgpu(uint64_t *out) {
return amdgpu_query_info(amdgpu_dev, AMDGPU_INFO_GTT_USAGE,
sizeof(uint64_t), out);
}
#ifdef HAS_AMDGPU_QUERY_SENSOR_INFO
static int getsclk_amdgpu(uint32_t *out) {
return amdgpu_query_sensor_info(amdgpu_dev, AMDGPU_INFO_SENSOR_GFX_SCLK,
sizeof(uint32_t), out);
}
static int getmclk_amdgpu(uint32_t *out) {
return amdgpu_query_sensor_info(amdgpu_dev, AMDGPU_INFO_SENSOR_GFX_MCLK,
sizeof(uint32_t), out);
}
#endif
#define DRM_ATLEAST_VERSION(maj, min) \
(drm_major > maj || (drm_major == maj && drm_minor >= min))
void init_amdgpu(int fd) {
uint32_t drm_major, drm_minor, out32;
uint64_t out64;
int ret;
if (amdgpu_device_initialize(fd, &drm_major, &drm_minor, &amdgpu_dev))
return;
if (!(ret = getgrbm_amdgpu(&out32)))
getgrbm = getgrbm_amdgpu;
else
drmError(ret, _("Failed to get GPU usage"));
#ifdef HAS_AMDGPU_QUERY_SENSOR_INFO
if (DRM_ATLEAST_VERSION(3, 11)) {
struct amdgpu_gpu_info gpu;
amdgpu_query_gpu_info(amdgpu_dev, &gpu);
sclk_max = gpu.max_engine_clk;
mclk_max = gpu.max_memory_clk;
if (!(ret = getsclk_amdgpu(&out32)))
getsclk = getsclk_amdgpu;
else
drmError(ret, _("Failed to get shader clock"));
if (!(ret = getmclk_amdgpu(&out32)))
getmclk = getmclk_amdgpu;
else // memory clock reporting not available on APUs
if (!(gpu.ids_flags & AMDGPU_IDS_FLAGS_FUSION))
drmError(ret, _("Failed to get memory clock"));
} else
fprintf(stderr, _("Clock frenquency reporting is disabled (amdgpu kernel driver 3.11.0 required)\n"));
#else
fprintf(stderr, _("Clock frequency reporting is not compiled in (libdrm 2.4.79 required)\n"));
#endif
struct drm_amdgpu_info_vram_gtt vram_gtt;
if ((ret = amdgpu_query_info(amdgpu_dev, AMDGPU_INFO_VRAM_GTT,
sizeof(vram_gtt), &vram_gtt))) {
drmError(ret, _("Failed to get VRAM size"));
return;
}
vramsize = vram_gtt.vram_size;
gttsize = vram_gtt.gtt_size;
if (!(ret = getvram_amdgpu(&out64)))
getvram = getvram_amdgpu;
else
drmError(ret, _("Failed to get VRAM usage"));
if (!(ret = getgtt_amdgpu(&out64)))
getgtt = getgtt_amdgpu;
else
drmError(ret, _("Failed to get GTT usage"));
}
void cleanup_amdgpu() {
if (amdgpu_dev)
amdgpu_device_deinitialize(amdgpu_dev);
}
|