diff --git a/amdgpu.c b/amdgpu.c index 135b4e5f..b7175fc4 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -15,9 +15,33 @@ */ #include "radeontop.h" -#include +#include #include #include +#include +#include +#include + +// kgd_pp_interface.h:amd_pp_sensors +#define AMDGPU_PP_SENSOR_VCN_POWER_STATE 25 + +int amdgpu_sensors_fd; + +static void init_amdgpu_sensors_fd(int drm_fd) { + struct stat st; + if (fstat(drm_fd, &st)) + abort(); + if ((st.st_mode & S_IFMT) != S_IFCHR || major(st.st_rdev) != 0xe2) { + fprintf(stderr, "init_amdgpu_sensors_fd weird fstat\n"); + return; + } + char buf[255]; + sprintf(buf, "/sys/kernel/debug/dri/%d/amdgpu_sensors", minor(st.st_rdev)); + amdgpu_sensors_fd = open(buf, O_RDONLY | O_CLOEXEC); + if (amdgpu_sensors_fd < 0) { + fprintf(stderr, "Couldn't open %s for VCN. Try sudo\n", buf); + } +} static amdgpu_device_handle amdgpu_dev; @@ -120,9 +144,30 @@ void init_amdgpu(int fd) { getgtt = getgtt_amdgpu; else drmError(ret, _("Failed to get GTT usage")); + + init_amdgpu_sensors_fd(fd); } void cleanup_amdgpu() { + if (amdgpu_sensors_fd) + close(amdgpu_sensors_fd); if (amdgpu_dev) amdgpu_device_deinitialize(amdgpu_dev); } + +int setupgetvcnungated(void) { + return amdgpu_sensors_fd > 0; +} + +void getvcnungated(uint32_t *out) { + *out = 0; + if (amdgpu_sensors_fd <= 0) + return; + const ssize_t ret = pread(amdgpu_sensors_fd, out, sizeof(uint32_t), + AMDGPU_PP_SENSOR_VCN_POWER_STATE * sizeof(uint32_t)); + if (ret != sizeof(uint32_t)) { + perror("pread"); + amdgpu_sensors_fd = 0; + *out = 0; + } +} diff --git a/detect.c b/detect.c index f9a1e843..cdc72c2e 100644 --- a/detect.c +++ b/detect.c @@ -361,6 +361,7 @@ void initbits(int fam) { bits.gui = (1U << 31); bits.uvd = 0; bits.vce0 = 0; + bits.vcnungated = 0; // R600 has a different texture bit, and only R600 has the TC, CR, SMX bits if (fam < RV770) { @@ -376,5 +377,9 @@ void initbits(int fam) { if (fam >= CAYMAN) { bits.vce0 = (1U << 7); } + } else if (fam > VEGA20) { // amdgpu_pm.c:amdgpu_debugfs_pm_info_pp +#ifdef ENABLE_AMDGPU + bits.vcnungated = setupgetvcnungated(); +#endif } } diff --git a/dump.c b/dump.c index d43288d5..1e232470 100644 --- a/dump.c +++ b/dump.c @@ -98,6 +98,7 @@ void dumpdata(const unsigned int ticks, const char file[], const unsigned int li float cb = 100 * results->cb * k; float uvd = 100 * results->uvd * k; float vce0 = 100 * results->vce0 * k; + float vcngate = 100 * results->vcnungated * k; float vram = 100.0f * results->vram / vramsize; float vrammb = results->vram / 1024.0f / 1024.0f; float gtt = 100.0f * results->gtt / gttsize; @@ -144,6 +145,9 @@ void dumpdata(const unsigned int ticks, const char file[], const unsigned int li fprintf(f, ", mclk %.2f%% %.3fghz, sclk %.2f%% %.3fghz", mclk, mclk_ghz, sclk, sclk_ghz); + if (bits.vcnungated) + fprintf(f, ", vcnungated %.2f%%", vce0); + fprintf(f, "\n"); fflush(f); diff --git a/include/radeontop.h b/include/radeontop.h index b1a13226..a508d264 100644 --- a/include/radeontop.h +++ b/include/radeontop.h @@ -25,6 +25,7 @@ #include "version.h" #include "gettext.h" +#include #include #include #include @@ -63,6 +64,9 @@ extern int (*getgtt)(uint64_t *out); extern int (*getsclk)(uint32_t *out); extern int (*getmclk)(uint32_t *out); +int setupgetvcnungated(void); +void getvcnungated(uint32_t *out); + // ticks.c void collect(unsigned int ticks, unsigned int dumpinterval); @@ -160,6 +164,7 @@ struct bits_t { unsigned int cr; unsigned int uvd; unsigned int vce0; + unsigned int vcnungated; uint64_t vram; uint64_t gtt; unsigned int sclk; diff --git a/ticks.c b/ticks.c index 90b8cab4..3809ad86 100644 --- a/ticks.c +++ b/ticks.c @@ -45,6 +45,8 @@ static void *collector(void *arg) { if (bits.uvd) getsrbm(&uvd); unsigned int vce; if (bits.vce0) getsrbm2(&vce); + unsigned int vcnungated; + if (bits.vcnungated) getvcnungated(&vcnungated); memset(&history[cur], 0, sizeof(struct bits_t)); @@ -64,6 +66,7 @@ static void *collector(void *arg) { if (stat & bits.cb) history[cur].cb = 1; if (uvd & bits.uvd) history[cur].uvd = 1; if (vce & bits.vce0) history[cur].vce0 = 1; + if (vcnungated & bits.vcnungated) history[cur].vcnungated = 1; getsclk(&history[cur].sclk); getmclk(&history[cur].mclk); @@ -94,6 +97,7 @@ static void *collector(void *arg) { res[curres].cr += history[i].cr; res[curres].uvd += history[i].uvd; res[curres].vce0 += history[i].vce0; + res[curres].vcnungated += history[i].vcnungated; res[curres].mclk += history[i].mclk; res[curres].sclk += history[i].sclk; } diff --git a/ui.c b/ui.c index 1dc15ca1..2ecb8438 100644 --- a/ui.c +++ b/ui.c @@ -152,6 +152,7 @@ void present(const unsigned int ticks, const char card[], unsigned int color, float cb = 100 * results->cb * k; float uvd = 100 * results->uvd * k; float vce0 = 100 * results->vce0 * k; + float vcnungated = 100 * results->vcnungated * k; float vram = 100.0f * results->vram / vramsize; float vrammb = results->vram / 1024.0f / 1024.0f; float vramsizemb = vramsize / 1024.0f / 1024.0f; @@ -286,6 +287,11 @@ void present(const unsigned int ticks, const char card[], unsigned int color, if (color) attroff(COLOR_PAIR(3)); } + if (bits.vcnungated) { + percentage(start, w, vcnungated); + printright(start++, hw, _("VCN ON/OFF %6.2f%%"), vcnungated); + } + //move the cursor away to fix some resizing artifacts on some terminals move(0,0);