Skip to content
This repository has been archived by the owner on Mar 20, 2022. It is now read-only.

Commit

Permalink
Move device dependent code to amdgpu.c and radeon.c
Browse files Browse the repository at this point in the history
  • Loading branch information
trek00 committed Aug 14, 2019
1 parent b4ceddb commit 38c0c09
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 139 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ xcb ?= 1

bin = radeontop
xcblib = libradeontop_xcb.so
src = $(filter-out auth_xcb.c,$(wildcard *.c))
obj = $(src:.c=.o)
src = $(filter-out amdgpu.c auth_xcb.c,$(wildcard *.c))
verh = include/version.h

CFLAGS_SECTIONED = -ffunction-sections -fdata-sections
Expand Down Expand Up @@ -52,6 +51,7 @@ else
endif

ifeq ($(amdgpu), 1)
src += amdgpu.c
CFLAGS += -DENABLE_AMDGPU=1
LIBS += $(shell pkg-config --libs libdrm_amdgpu)

Expand All @@ -68,6 +68,7 @@ else ifndef nostrip
endif
endif

obj = $(src:.c=.o)
LDFLAGS ?= -Wl,-O1
LDFLAGS += $(LDFLAGS_SECTIONED)
LIBS += $(shell pkg-config --libs pciaccess)
Expand Down
88 changes: 88 additions & 0 deletions amdgpu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
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 <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

void init_amdgpu(int fd) {
uint32_t drm_major, drm_minor;
int ret;

if (amdgpu_device_initialize(fd, &drm_major, &drm_minor, &amdgpu_dev))
die(_("Can't initialize amdgpu driver"));

getgrbm = getgrbm_amdgpu;

#ifdef HAS_AMDGPU_QUERY_SENSOR_INFO
struct amdgpu_gpu_info gpu;

amdgpu_query_gpu_info(amdgpu_dev, &gpu);
sclk_max = gpu.max_engine_clk;
mclk_max = gpu.max_memory_clk;
getsclk = getsclk_amdgpu;
getmclk = getmclk_amdgpu;
#else
printf(_("amdgpu DRM driver is used, but clock reporting is not enabled\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))) {
printf(_("Failed to get VRAM size, error %d\n"), ret);
return;
}

vramsize = vram_gtt.vram_size;
gttsize = vram_gtt.gtt_size;
getvram = getvram_amdgpu;
getgtt = getgtt_amdgpu;
}

void cleanup_amdgpu() {
if (amdgpu_dev)
amdgpu_device_deinitialize(amdgpu_dev);
}
130 changes: 2 additions & 128 deletions detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ uint64_t vramsize;
uint64_t gttsize;
unsigned int sclk_max = 0; // kilohertz
unsigned int mclk_max = 0; // kilohertz
int drm_fd = -1;
char drm_name[10] = ""; // should be radeon or amdgpu
const void *area;

// function pointers to the right backend
Expand All @@ -35,12 +33,6 @@ int (*getgtt)(uint64_t *out);
int (*getsclk)(uint32_t *out);
int (*getmclk)(uint32_t *out);

#ifdef ENABLE_AMDGPU
#include <libdrm/amdgpu_drm.h>
#include <libdrm/amdgpu.h>
amdgpu_device_handle amdgpu_dev;
#endif

struct pci_device * findGPUDevice(const unsigned char bus) {
struct pci_device *dev;
struct pci_id_match match;
Expand Down Expand Up @@ -72,126 +64,6 @@ struct pci_device * findGPUDevice(const unsigned char bus) {
return dev;
}

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));
}

static int getgrbm_radeon(uint32_t *out) {
*out = GRBM_STATUS;
return radeon_get_drm_value(drm_fd, RADEON_INFO_READ_REG, out);
}

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);
}

void init_radeon(int fd) {
int drm_major, drm_minor, ret;
drmVersionPtr ver = drmGetVersion(fd);

drm_major = ver->version_major;
drm_minor = ver->version_minor;
drmFreeVersion(ver);
getgrbm = getgrbm_radeon;

if (drm_major > 2 || (drm_major == 2 && drm_minor >= 36)) {
struct drm_radeon_gem_info gem;

if ((ret = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
&gem, sizeof(gem)))) {
printf(_("Failed to get VRAM size, error %d\n"), ret);
return;
}

vramsize = gem.vram_size;
gttsize = gem.gart_size;
getvram = getvram_radeon;
getgtt = getgtt_radeon;
} else
printf(_("Kernel too old for VRAM reporting.\n"));
}

#ifdef ENABLE_AMDGPU
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

void init_amdgpu(int fd) {
uint32_t drm_major, drm_minor;
int ret;

if (amdgpu_device_initialize(fd, &drm_major, &drm_minor, &amdgpu_dev))
die(_("Can't initialize amdgpu driver"));

getgrbm = getgrbm_amdgpu;

#ifdef HAS_AMDGPU_QUERY_SENSOR_INFO
struct amdgpu_gpu_info gpu;

amdgpu_query_gpu_info(amdgpu_dev, &gpu);
sclk_max = gpu.max_engine_clk;
mclk_max = gpu.max_memory_clk;
getsclk = getsclk_amdgpu;
getmclk = getmclk_amdgpu;
#else
printf(_("amdgpu DRM driver is used, but clock reporting is not enabled\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))) {
printf(_("Failed to get VRAM size, error %d\n"), ret);
return;
}

vramsize = vram_gtt.vram_size;
gttsize = vram_gtt.gtt_size;
getvram = getvram_amdgpu;
getgtt = getgtt_amdgpu;
}

void cleanup_amdgpu() {
if (amdgpu_dev)
amdgpu_device_deinitialize(amdgpu_dev);
}
#endif

static int getgrbm_mem(uint32_t *out) {
*out = *(uint32_t *)((const char *) area + 0x10);
return 0;
Expand All @@ -204,6 +76,8 @@ static int getuint64_null(uint64_t *out) { UNUSED(out); return -1; }

void init_pci(unsigned char *bus, unsigned int *device_id, const unsigned char forcemem) {
int use_ioctl = 0;
int drm_fd = -1;
char drm_name[10] = ""; // should be radeon or amdgpu

getgrbm = getsclk = getmclk = getuint32_null;
getvram = getgtt = getuint64_null;
Expand Down
16 changes: 7 additions & 9 deletions include/radeontop.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,13 @@
#include <signal.h>
#include <locale.h>
#include <xf86drm.h>
#include <radeon_drm.h>
#include <stdint.h>

enum {
GRBM_STATUS = 0x8010,
MMAP_SIZE = 0x14
};

#ifndef RADEON_INFO_VRAM_USAGE
#define RADEON_INFO_VRAM_USAGE 0x1e
#endif
#ifndef RADEON_INFO_READ_REG
#define RADEON_INFO_READ_REG 0x24
#endif

// auth.c
void authenticate_drm(int fd);

Expand Down Expand Up @@ -164,6 +156,12 @@ extern uint64_t vramsize;
extern uint64_t gttsize;
extern unsigned int sclk_max;
extern unsigned int mclk_max;
extern int drm_fd;

// radeon.c
void init_radeon(int fd);

// amdgpu.c
void init_amdgpu(int fd);
void cleanup_amdgpu();

#endif
73 changes: 73 additions & 0 deletions radeon.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
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>

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));
}

static int getgrbm_radeon(uint32_t *out) {
*out = GRBM_STATUS;
return radeon_get_drm_value(drm_fd, RADEON_INFO_READ_REG, out);
}

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);
}

void init_radeon(int fd) {
int drm_major, drm_minor, ret;
drmVersionPtr ver = drmGetVersion(fd);

drm_fd = fd;
drm_major = ver->version_major;
drm_minor = ver->version_minor;
drmFreeVersion(ver);
getgrbm = getgrbm_radeon;

if (drm_major > 2 || (drm_major == 2 && drm_minor >= 36)) {
struct drm_radeon_gem_info gem;

if ((ret = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
&gem, sizeof(gem)))) {
printf(_("Failed to get VRAM size, error %d\n"), ret);
return;
}

vramsize = gem.vram_size;
gttsize = gem.gart_size;
getvram = getvram_radeon;
getgtt = getgtt_radeon;
} else
printf(_("Kernel too old for VRAM reporting.\n"));
}

0 comments on commit 38c0c09

Please sign in to comment.