Bug 75401

Summary: vgaswitcheroo doesn't work for AMD Radeon 8870m (possibly due to "wrong" PCI class)
Product: Drivers Reporter: drill87
Component: Video(DRI - non Intel)Assignee: drivers_video-dri
Severity: low CC: alexdeucher, pali
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 3.11.10 Tree: Mainline
Regression: No
Attachments: Output of "lspci -nn" command
fix for rom fetching
dmesg after applying "fix for rom fetching" patch
dmesg before applying "fix for rom fetching" patch
preffer current pci device

Description drill87 2014-05-03 17:26:49 UTC
I've got Samsung 870Z5E notebook equipped with AMD Radeon 8870m video card (and Intel HD 4000 graphics). I always failed to use vgaswitcheroo to disable the discrete card -- there wasn't even its entry in debugfs. 

After a little investigetion of radeon module's source code I found, that the problem happens, possibly, due to "unusual" PCI class of my Radeon 8870m. According to command "lspci -nn" Radeon 8870m has PCI class id 0380, which is corresponds to PCI_CLASS_DISPLAY_OTHER (in pci_ids.h). On the other hand, when radeon module check number of videocards, it excepts them to have class PCI_CLASS_DISPLAY_VGA (0300). Thus module concludes that I have only 1 videocard (Intel HD, which has 0300 class id) and decides, that there's no need for vgaswitcheroo to be initialized.

I tried to edit radeon kernel module by adding additional checks for PCI_CLASS_DISPLAY_OTHER class id (in 2 places). After that vgaswitcheroo started to work -- the entry appeared in debugfs and I could disable the discrete graphics card. Though I'm not sure if everything went right because I failed to use radeon card for actual rendering through DRI PRIME even in the newest kernel stable version (3.14.2) -- X server crashes even if I try to issues glxinfo command.
Comment 1 drill87 2014-05-03 17:29:50 UTC
Created attachment 134941 [details]
Output of "lspci -nn" command

This log has wring revision number for radeon 8870m (rev ff), because right now I'm shutting it out through acpi_call command. Everything else is right.
Comment 3 drill87 2014-05-06 04:36:28 UTC
Yes, it fixes vgaswitcheroo problem. Sorry for misleading bugreport then.

However, I would like to mention that radeon module had 2 places with "problematic" PCI class test.

The first one is fixed with the aforementioned patch.

The second place is in file "radeon_bios.c" in function "static bool radeon_atrm_get_bios(struct radeon_device *rdev)". I don't know if it is a problem, but it's still expected only cards with PCI_CLASS_DISPLAY_VGA class there. Thus, I guess, the bios doesn't get initialized properly for my card with class PCI_CLASS_DISPLAY_OTHER...

Anyway, thank you for your time!
Comment 4 Alex Deucher 2014-05-06 13:09:52 UTC
Created attachment 135221 [details]
fix for rom fetching

Does this patch fix the issue?
Comment 5 drill87 2014-05-09 06:14:01 UTC
I guess it fixes. At least, I can see no errors for radeon module in dmesg. Vgaswitcheroo, as I aforementioned, works too (I can turn off the card, so notebook heats less). 

However, I cannot say any more, because I fail to actually use my radeon for rendering (with Xorg server 1.15.1) --- even command "glxinfo" with "DRI_PRIME=1" (and configured offload sink) crashes Xserver. And I don't know where the problem might be - in module or in Xorg drivers.
Comment 6 drill87 2014-05-09 06:15:04 UTC
Created attachment 135541 [details]
dmesg after applying "fix for rom fetching" patch
Comment 7 Pali Rohár 2014-05-09 12:44:30 UTC
@drill87: I had same problem (Xorg server crashing) when I tried to use DRI_PRIME on 8690M. I fixed it with updating libdri, mesa, radeon & intel xorg drivers from git. And then it started working. Also I removed everything in /etc/X11/xorg.conf and /etc/X11/xorg.conf.d/ and called xrandr --setprovideroutputsource 1 0 before running DRI_PRIME=1 glxinfo

@Alex Deucher: Why is needed to use acpi "ATRM"? If you still remember https://bugzilla.kernel.org/show_bug.cgi?id=73901#c9 I needed only to patch radeon_atpx_handler.c. So my radeon card working fine without "ATRM". When "ATRM" is used? Or for which functions?
Comment 8 Alex Deucher 2014-05-09 13:05:57 UTC
ATRM is an acpi method for fetching the rom on certain systems.  If your system was able to fetch the rom via another method, it may not use ATRM.

I'm not sure if the ATRM method is required in drill87's case either, but he claimed that it wasn't able to find the rom.  Drill87, can you attach the dmesg output without the patch?
Comment 9 drill87 2014-05-09 13:53:04 UTC
Oh, I'm sorry, it seems I didn't write it clear enough. I mentioned file "radeon_bios.c" only because I saw there too goes PCI class checl only against PCI_CLASS_DISPLAY_VGA, but there wasn't additional test for PCI_CLASS_DISPLAY_OTHER . I guessed that it might possibly cause problems (just as it did for vgaswitcherro). Though I don't know if it really does (and if it does specifically on my computer). I don't even know what ATRM is :) 

So I'm sorry again for mislead I've done. And thanks for the tip about libdri and xorg drivers update!
Comment 10 drill87 2014-05-09 13:54:17 UTC
Created attachment 135561 [details]
dmesg before applying "fix for rom fetching" patch
Comment 11 Alex Deucher 2014-05-09 14:35:11 UTC
Looks like it works fine without the patch as well.  That said, the ATRM patch shouldn't hurt anything if there ever ends up being a case where the ATRM method is hung off a non-VGA display device.
Comment 12 Pali Rohár 2014-05-18 20:02:45 UTC
@Alex Deucher: Why is this bug while loop needed?

static bool radeon_atrm_get_bios(struct radeon_device *rdev)
	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
		dhandle = ACPI_HANDLE(&pdev->dev);
		if (!dhandle)

		status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
		if (!ACPI_FAILURE(status)) {
			found = true;

Is not correct to use ACPI_HANDLE directly, something like this (without while loop)?

static bool radeon_atrm_get_bios(struct radeon_device *rdev)
	if (rdev->pdev)
		dhandle = ACPI_HANDLE(&rdev->pdev->dev);

This could also eliminate using PCI_CLASS_DISPLAY_VGA.

If I understood correctly, ATRM method is specific for AMD cards so searching for ATRM method in all avalilable pci devices (which match class) is not necessary.
Comment 13 Alex Deucher 2014-05-19 02:04:29 UTC
(In reply to Pali Rohár from comment #12)
> @Alex Deucher: Why is this bug while loop needed?

IIRC, sometimes the method is hung off the other GPU.
Comment 14 Pali Rohár 2014-05-26 08:42:55 UTC
Created attachment 137381 [details]
preffer current pci device

What about this patch? It will preffer to call ATRM method for current pci device.
Comment 15 Pali Rohár 2014-05-26 08:48:53 UTC
oups, it should be ACPI_HANDLE(&rdev->pdev->dev) and not ACPI_HANDLE(&pdev->dev).