Commit 586bc4aa authored by Alex Deucher's avatar Alex Deucher Committed by Takashi Iwai
Browse files

ALSA: hda/hdmi - fix vgaswitcheroo detection for AMD



Only enable the vga_switcheroo logic on systems with the
ATPX ACPI method.  This logic is not needed for asics
that are not part of a PX (PowerXpress)/HG (Hybrid Graphics)
platform.

Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
Acked-by: default avatarEvan Quan <evan.quan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/r/20191122214353.582899-2-alexander.deucher@amd.com


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent bf2aa5ca
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <linux/clocksource.h>
#include <linux/time.h>
#include <linux/completion.h>
#include <linux/acpi.h>

#ifdef CONFIG_X86
/* for snoop control */
@@ -1401,6 +1402,34 @@ static int azx_dev_free(struct snd_device *device)
}

#ifdef SUPPORT_VGA_SWITCHEROO
#ifdef CONFIG_ACPI
/* ATPX is in the integrated GPU's namespace */
static bool atpx_present(void)
{
	struct pci_dev *pdev = NULL;
	acpi_handle dhandle, atpx_handle;
	acpi_status status;

	while ((pdev = pci_get_class(PCI_BASE_CLASS_DISPLAY << 16, pdev)) != NULL) {
		dhandle = ACPI_HANDLE(&pdev->dev);
		if (dhandle) {
			status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
			if (!ACPI_FAILURE(status)) {
				pci_dev_put(pdev);
				return true;
			}
		}
		pci_dev_put(pdev);
	}
	return false;
}
#else
static bool atpx_present(void)
{
	return false;
}
#endif

/*
 * Check of disabled HDMI controller by vga_switcheroo
 */
@@ -1412,6 +1441,22 @@ static struct pci_dev *get_bound_vga(struct pci_dev *pci)
	switch (pci->vendor) {
	case PCI_VENDOR_ID_ATI:
	case PCI_VENDOR_ID_AMD:
		if (pci->devfn == 1) {
			p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
							pci->bus->number, 0);
			if (p) {
				/* ATPX is in the integrated GPU's ACPI namespace
				 * rather than the dGPU's namespace. However,
				 * the dGPU is the one who is involved in
				 * vgaswitcheroo.
				 */
				if (((p->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
				    atpx_present())
					return p;
				pci_dev_put(p);
			}
		}
		break;
	case PCI_VENDOR_ID_NVIDIA:
		if (pci->devfn == 1) {
			p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),