Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions amdgpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,33 @@ void init_amdgpu(int fd) {
if (amdgpu_device_initialize(fd, &drm_major, &drm_minor, &amdgpu_dev))
return;

// Query GFX IP version for family detection fallback
{
struct drm_amdgpu_info_hw_ip gfx_ip = {};
if (!amdgpu_query_hw_ip_info(amdgpu_dev, AMDGPU_HW_IP_GFX,
0, &gfx_ip)) {
unsigned int major = gfx_ip.hw_ip_version_major;
unsigned int minor_raw = gfx_ip.hw_ip_version_minor;
unsigned int minor, rev;

/*
* Newer kernels encode (minor << 8 | rev) in
* hw_ip_version_minor. GFX11+ only exists on
* these kernels, and for GFX10 a value >= 256
* is unambiguously the new encoding.
*/
if (major >= 11 || minor_raw >= 256) {
minor = (minor_raw >> 8) & 0xff;
rev = minor_raw & 0xff;
} else {
minor = minor_raw;
rev = 0;
}

gfx_version = major * 100 + minor * 10 + rev;
}
}

if (!(ret = getgrbm_amdgpu(&out32))) {
getgrbm = getgrbm_amdgpu;
getsrbm = getsrbm_amdgpu;
Expand Down
52 changes: 52 additions & 0 deletions detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <errno.h>

struct bits_t bits;
unsigned int gfx_version;
uint64_t vramsize;
uint64_t gttsize;
unsigned int sclk_max = 0; // kilohertz
Expand Down Expand Up @@ -341,6 +342,57 @@ int getfamily(unsigned int id) {
return 0;
}

int getfamily_gfx(unsigned int gfx_ver) {

switch(gfx_ver) {
// RDNA 1 (GFX10.1)
case 1010: return NAVI10;
case 1011: return NAVI12;
case 1012: return NAVI14;
// RDNA 2 (GFX10.3)
case 1030: return SIENNA_CICHLID;
case 1031: return NAVY_FLOUNDER;
case 1032: return DIMGREY_CAVEFISH;
case 1033: return GFX1033;
case 1034: return GFX1034;
case 1035: return YELLOW_CARP;
case 1036: return MENDOCINO;
// RDNA 3 (GFX11.0)
case 1100: return NAVI31;
case 1101: return NAVI32;
case 1102: return NAVI33;
case 1103: return GFX1103;
// RDNA 3.5 (GFX11.5)
case 1150: return GFX1150;
case 1151: return GFX1151;
// RDNA 4m (GFX11.7)
case 1170: return GFX1170;
case 1171: return GFX1171;
case 1172: return GFX1172;
// RDNA 4 (GFX12.0)
case 1200: return GFX1200;
case 1201: return GFX1201;
// RDNA 5 (GFX13)
case 1300: return GFX1300;
case 1310: return GFX1310;
}

// Fallback: recognize family by major.minor
unsigned int major_minor = (gfx_ver / 10) * 10;
switch(major_minor) {
case 1010: return NAVI10;
case 1030: return SIENNA_CICHLID;
case 1100: return NAVI31;
case 1150: return GFX1150;
case 1170: return GFX1170;
case 1200: return GFX1200;
case 1300: return GFX1300;
case 1310: return GFX1310;
}

return 0;
}

void initbits(int fam) {

// The majority of these is the same from R600 to Southern Islands.
Expand Down
16 changes: 16 additions & 0 deletions family_str.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,20 @@ const char * const family_str[] = {
str(ALDEBARAN),
str(CYAN_SKILLFISH),
str(BEIGE_GOBY),
str(MENDOCINO),
str(GFX1033),
str(GFX1034),
str(NAVI31),
str(NAVI32),
str(NAVI33),
str(GFX1103),
str(GFX1150),
str(GFX1151),
str(GFX1170),
str(GFX1171),
str(GFX1172),
str(GFX1200),
str(GFX1201),
str(GFX1300),
str(GFX1310),
};
18 changes: 18 additions & 0 deletions include/radeontop.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ void die(const char *why);
// detect.c
void init_pci(const char *path, short *bus, unsigned int *device_id, const unsigned char forcemem);
int getfamily(unsigned int id);
int getfamily_gfx(unsigned int gfx_ver);
void initbits(int fam);
void cleanup();

Expand Down Expand Up @@ -138,6 +139,22 @@ enum radeon_family {
ALDEBARAN,
CYAN_SKILLFISH,
BEIGE_GOBY,
MENDOCINO, // gfx1036
GFX1033, // Steam Deck (Van Gogh custom)
GFX1034, // Navi 24
NAVI31, // gfx1100
NAVI32, // gfx1101
NAVI33, // gfx1102
GFX1103, // Radeon 780M iGPU
GFX1150, // Strix
GFX1151, // Strix Halo
GFX1170, // RDNA 4m
GFX1171,
GFX1172,
GFX1200, // RDNA 4
GFX1201,
GFX1300, // RDNA 5
GFX1310,
};

extern const char * const family_str[];
Expand Down Expand Up @@ -178,5 +195,6 @@ void init_radeon(int fd, int drm_major, int drm_minor);
// amdgpu.c
void init_amdgpu(int fd);
void cleanup_amdgpu();
extern unsigned int gfx_version;

#endif
31 changes: 29 additions & 2 deletions radeontop.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,38 @@ int main(int argc, char **argv) {

setuid(getuid());

const int family = getfamily(device_id);
// The GC (Graphics & Compute) block number queried from
// amdgpu_query_hw_ip_info() identifies the chip unambiguously,
// while PCI device IDs are reused by AMD across APU SKUs (e.g.
// 0x150E is shared by Strix Point gfx1150 and Krackan Point
// gfx1152). When both are available, the GC number wins. PCI
// lookup is the fallback for legacy cards that don't expose a
// GC number (radeon driver, or amdgpu without IP query support).
int family = 0;
if (gfx_version)
family = getfamily_gfx(gfx_version);
if (!family)
family = getfamily(device_id);
if (!family)
fprintf(stderr, _("Unknown Radeon card. <= R500 won't work, new cards might.\n"));

const char * const cardname = family_str[family];
// When the family is unknown but a GC number is available, show
// the GC number (which we know for certain) together with the
// best-guess GFX shader target (gfxNNNN?). The two coincide for
// GC 10.x but diverge for GC 11.0.x APUs, hence the '?' on GFX.
static char gfx_fallback[40];
const char *cardname;
if (!family && gfx_version) {
snprintf(gfx_fallback, sizeof(gfx_fallback),
"gfx%u? (GC %u.%u.%u unknown)",
gfx_version,
gfx_version / 100,
(gfx_version / 10) % 10,
gfx_version % 10);
cardname = gfx_fallback;
} else {
cardname = family_str[family];
}

initbits(family);

Expand Down