summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2019-11-22 16:43:50 -0500
committerTakashi Iwai <tiwai@suse.de>2019-11-26 16:53:51 +0100
commit586bc4aab878efcf672536f0cdec3d04b6990c94 (patch)
tree026a7940b807cdf8cc74bae645658f70f9526e9a
parentbf2aa5cadd1c7bb91af4b5b1218e643cfffb5c9a (diff)
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: Takashi Iwai <tiwai@suse.de> Acked-by: Evan Quan <evan.quan@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Link: https://lore.kernel.org/r/20191122214353.582899-2-alexander.deucher@amd.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_intel.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index e76a0bb6d3cf..ff098957e30f 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -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),