-
Notifications
You must be signed in to change notification settings - Fork 71
/
radeon.c
151 lines (122 loc) · 4.26 KB
/
radeon.c
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
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 <radeon_drm.h>
#include <xf86drm.h>
// It's safe to make these queries on older kernels.
#ifndef RADEON_INFO_VRAM_USAGE
#define RADEON_INFO_VRAM_USAGE 0x1e
#endif
#ifndef RADEON_INFO_READ_REG
#define RADEON_INFO_READ_REG 0x24
#endif
#ifndef RADEON_INFO_CURRENT_GPU_SCLK
#define RADEON_INFO_CURRENT_GPU_SCLK 0x22
#endif
#ifndef RADEON_INFO_CURRENT_GPU_MCLK
#define RADEON_INFO_CURRENT_GPU_MCLK 0x23
#endif
static int drm_fd;
static int radeon_get_drm_value(int fd, unsigned request, uint32_t *out) {
struct drm_radeon_info info;
memset(&info, 0, sizeof(info));
info.value = (unsigned long) out;
info.request = request;
return drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
}
#ifdef RADEON_INFO_READ_REG
static int getgrbm_radeon(uint32_t *out) {
*out = GRBM_STATUS;
return radeon_get_drm_value(drm_fd, RADEON_INFO_READ_REG, out);
}
static int getsrbm_radeon(uint32_t *out) {
*out = SRBM_STATUS;
return radeon_get_drm_value(drm_fd, RADEON_INFO_READ_REG, out);
}
static int getsrbm2_radeon(uint32_t *out) {
*out = SRBM_STATUS2;
return radeon_get_drm_value(drm_fd, RADEON_INFO_READ_REG, out);
}
static int getsclk_radeon(uint32_t *out) {
return radeon_get_drm_value(drm_fd, RADEON_INFO_CURRENT_GPU_SCLK, out);
}
static int getmclk_radeon(uint32_t *out) {
return radeon_get_drm_value(drm_fd, RADEON_INFO_CURRENT_GPU_MCLK, out);
}
#endif
#ifdef RADEON_INFO_VRAM_USAGE
static int getvram_radeon(uint64_t *out) {
return radeon_get_drm_value(drm_fd, RADEON_INFO_VRAM_USAGE,
(uint32_t *) out);
}
static int getgtt_radeon(uint64_t *out) {
return radeon_get_drm_value(drm_fd, RADEON_INFO_GTT_USAGE,
(uint32_t *) out);
}
#endif
#define DRM_ATLEAST_VERSION(maj, min) \
(drm_major > maj || (drm_major == maj && drm_minor >= min))
void init_radeon(int fd, int drm_major, int drm_minor) {
int ret;
uint32_t out32 __attribute__((unused));
uint64_t out64 __attribute__((unused));
drm_fd = fd;
#ifdef RADEON_INFO_READ_REG
if (DRM_ATLEAST_VERSION(2, 42)) {
if (!(ret = getgrbm_radeon(&out32))) {
getgrbm = getgrbm_radeon;
getsrbm = getsrbm_radeon;
getsrbm2 = getsrbm2_radeon;
} else
drmError(ret, _("Failed to get GPU usage"));
if ((ret = radeon_get_drm_value(drm_fd, RADEON_INFO_MAX_SCLK,
&sclk_max)))
drmError(ret, _("Failed to get maximum shader clock"));
mclk_max = 0; // no max memory clock info on radeon
if (!(ret = getsclk_radeon(&out32)))
getsclk = getsclk_radeon;
else
drmError(ret, _("Failed to get shader clock"));
if (!(ret = getmclk_radeon(&out32)))
getmclk = getmclk_radeon;
else
drmError(ret, _("Failed to get memory clock"));
} else
fprintf(stderr, _("GPU usage reporting via libdrm is disabled (radeon kernel driver 2.42.0 required), attempting memory path\n"));
#else
fprintf(stderr, _("GPU usage reporting via libdrm is not compiled in (libdrm 2.4.71 required), attempting memory path\n"));
#endif
#ifdef RADEON_INFO_VRAM_USAGE
if (DRM_ATLEAST_VERSION(2, 39)) {
struct drm_radeon_gem_info gem;
if ((ret = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
&gem, sizeof(gem)))) {
drmError(ret, _("Failed to get VRAM size"));
return;
}
vramsize = gem.vram_size;
gttsize = gem.gart_size;
if (!(ret = getvram_radeon(&out64)))
getvram = getvram_radeon;
else
drmError(ret, _("Failed to get VRAM usage"));
if (!(ret = getgtt_radeon(&out64)))
getgtt = getgtt_radeon;
else
drmError(ret, _("Failed to get GTT usage"));
} else
fprintf(stderr, _("Memory usage reporting is disabled (radeon kernel driver 2.39.0 required)\n"));
#else
fprintf(stderr, _("Memory usage reporting is not compiled in (libdrm 2.4.53 required)\n"));
#endif
}