Skip to content

fix(amdgpu): ask the driver whether a GPU is integrated - #37

Open
6jrx wants to merge 1 commit into
ShadowBlip:mainfrom
6jrx:fix/integrated-gpu-detection
Open

fix(amdgpu): ask the driver whether a GPU is integrated#37
6jrx wants to merge 1 commit into
ShadowBlip:mainfrom
6jrx:fix/integrated-gpu-detection

Conversation

@6jrx

@6jrx 6jrx commented Aug 22, 2026

Copy link
Copy Markdown

Fixes #28, at least the direction the title describes.

The problem

get_gpu() derives the integrated / dedicated class from the PCI class code alone, but that code doesn't say where the GPU lives — it says whether the GPU is the boot VGA device. An APU enumerates as 030000 (VGA compatible controller) when its iGPU is the boot VGA device and as 038000 (display controller) when it isn't. In the second case it gets classified dedicated, AmdGpu::get_tdp_interface() returns None, and the device is left with no TDP control at all.

That's what's happening on Strix Point handhelds — GPD Win Mini / Win Max 2 / Win 4 HX370, reported downstream as ublue-os/bazzite#5382:

$ lspci -nn | grep -i display
64:00.0 Display controller [0380]: Advanced Micro Devices, Inc. [AMD/ATI] Strix [Radeon 880M / 890M] [1002:150e] (rev c1)

$ cat /sys/class/drm/card1/device/class
0x038000
powerstation[1527]: WARN  [powerstation] Card Card1 does not have a TDP interface
steamos-manager[1567]: ERROR steamos_manager::power: Error calling Get for MinTdp:
  org.freedesktop.DBus.Error.UnknownInterface: Unknown interface 'org.shadowblip.GPU.Card.TDP'

The fix

Ask the driver, as suggested in #28. AMDGPU_INFO_DEV_INFO reports AMDGPU_IDS_FLAGS_FUSION, which amdgpu sets for every APU — the same flag switcheroo-control looks at. It's queried through a small libc::ioctl wrapper so that libdrm doesn't have to be pulled in.

The correction only runs when the PCI class code did not already say integrated, and it can only ever promote a card to integrated. Every device that works today keeps exactly the class it has today, and if the query can't be answered — no render node, not an amdgpu device, no access to /dev/dri — the existing behaviour is kept. Intel is untouched.

Testing

All on a GPD WIN 4 (Ryzen AI 9 HX 370 / Radeon 890M), i.e. the affected hardware.

The query itself:

running 1 test
test performance::gpu::amd::drm::tests::queries_every_reachable_amd_card ... ok

---- performance::gpu::amd::drm::tests::queries_every_reachable_amd_card stdout ----
card1: is_apu = Some(true)

And the daemon. Before:

WARN  [powerstation] Card Card1 does not have a TDP interface

After:

DEBUG [powerstation::performance::gpu::dbus::gpu] Driver reports /sys/class/drm/card1 as an APU, correcting class to integrated
INFO  [powerstation::performance::gpu::amd::tdp] Found Hardware interface for TDP control
DEBUG [powerstation] Discovered TDP interface on card: Card1

That run was unprivileged, so RyzenAdj init fails with EIO and the bus name can't be owned afterwards; neither has anything to do with the classification.

The added test skips itself when there's no reachable AMD card, so it's a no-op on CI runners.

Not addressed

A discrete GPU that is the boot VGA device reports 030000 and is still classified integrated, which is the other half of #28. Happy to widen the check to always consult the driver — I kept it narrow so that no currently-working device changes classification, and so that a runtime-suspended discrete GPU isn't woken just to be asked.

The PCI class code does not tell us whether a GPU is integrated: an APU
enumerates as 030000 when its iGPU is the boot VGA device and as 038000
when it is not. Any APU that is not the boot VGA device was therefore
treated as discrete and never got a TDP interface, leaving the device
with no TDP control at all.

Query AMDGPU_INFO_DEV_INFO instead and look at AMDGPU_IDS_FLAGS_FUSION,
which the driver sets for every APU, and use it to correct the class when
the PCI class code suggests the GPU is discrete.

Fixes ShadowBlip#28

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Some iGPUs are incorrectly detected as dGPUs

1 participant