From: Daniel Drake <drake@endlessm.com>
To: bhelgaas@google.com
Cc: linux-pci@vger.kernel.org, linux@endlessm.com,
nouveau@lists.freedesktop.org, Lukas Wunner <lukas@wunner.de>,
Aaron Plattner <aplattner@nvidia.com>,
Peter Wu <peter@lekensteyn.nl>,
Ilia Mirkin <imirkin@alum.mit.edu>,
Karol Herbst <kherbst@redhat.com>,
Maik Freudenberg <hhfeuer@gmx.de>
Subject: [PATCH] PCI: Expose hidden NVIDIA HDA controllers
Date: Thu, 13 Jun 2019 14:35:14 +0800 [thread overview]
Message-ID: <20190613063514.15317-1-drake@endlessm.com> (raw)
From: Lukas Wunner <lukas@wunner.de>
The integrated HDA controller on Nvidia GPUs can be hidden with a bit in
the GPU's config space. Information about this scheme was provided by
NVIDIA on their forums.
Many laptops now ship with this device hidden, meaning that Linux users
of affected platforms (where the HDMI connector comes off the NVIDIA GPU)
cannot use HDMI audio functionality.
Avoid this issue by exposing the HDMI audio device on device enumeration
and resume.
The GPU and HDA controller are two functions of the same PCI device
(VGA class device on function 0 and audio device on function 1).
The multifunction flag in the GPU's Header Type register is cleared when
the HDA controller is hidden and set if it's exposed, so reread the flag
after exposing the HDA.
According to Ilia Mirkin, the HDA controller is only present from MCP89
onward, so do not touch config space on older GPUs.
This quirk is limited to NVIDIA PCI devices with the VGA Controller
device class. This is expected to correspond to product configurations
where the NVIDIA GPU has connectors attached. Other products where the
device class is 3D Controller are expected to correspond to configurations
where the NVIDIA GPU is dedicated (dGPU) and has no connectors.
It's sensible to avoid exposing the HDA controller on dGPU setups,
especially because we've seen cases where the PCI BARs are not set
up correctly by the platform in this case, causing Linux to log
errors if the device is visible. This assumption of device class
accurately corresponding to product configuration is true for 6 of 6
laptops recently checked at the Endless lab, and there are also signs of
agreement checking the data from 74 previously tested products, however
Ilia Mirkin comments that he's seen cases where it is not true. Anyway, it
looks like this quirk should fix audio support for the majority of
affected users.
This commit takes inspiration from an earlier patch by Daniel Drake.
Link: https://devtalk.nvidia.com/default/topic/1024022
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75985
Cc: Aaron Plattner <aplattner@nvidia.com>
Cc: Peter Wu <peter@lekensteyn.nl>
Cc: Ilia Mirkin <imirkin@alum.mit.edu>
Cc: Karol Herbst <kherbst@redhat.com>
Cc: Maik Freudenberg <hhfeuer@gmx.de>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Tested-by: Daniel Drake <drake@endlessm.com>
---
drivers/pci/quirks.c | 28 ++++++++++++++++++++++++++++
include/linux/pci_ids.h | 1 +
2 files changed, 29 insertions(+)
Submitting Lukas's patch from over a year ago.
It got held up before on patch dependencies (which are now all merged)
and also the concern around the device class assumption not being true
in all cases. However, there hasn't been any progress towards finding a
better approach, and we don't have any logs to hand from the cases where
this isn't true, so I think we should go with this approach which will
work in the (vast?) majority of cases.
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 0f16acc323c6..52046b517e2e 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4971,6 +4971,34 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_AMD, PCI_ANY_ID,
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
+/*
+ * Many laptop BIOSes hide the integrated HDA controller on NVIDIA GPUs
+ * via a special bit. This prevents Linux from seeing and using it.
+ * Unhide it here.
+ * https://devtalk.nvidia.com/default/topic/1024022
+ */
+static void quirk_nvidia_hda(struct pci_dev *gpu)
+{
+ u8 hdr_type;
+ u32 val;
+
+ /* there was no integrated HDA controller before MCP89 */
+ if (gpu->device < PCI_DEVICE_ID_NVIDIA_GEFORCE_320M)
+ return;
+
+ /* bit 25 at offset 0x488 hides or exposes the HDA controller */
+ pci_read_config_dword(gpu, 0x488, &val);
+ pci_write_config_dword(gpu, 0x488, val | BIT(25));
+
+ /* the GPU becomes a multifunction device when the HDA is exposed */
+ pci_read_config_byte(gpu, PCI_HEADER_TYPE, &hdr_type);
+ gpu->multifunction = !!(hdr_type & BIT(7));
+}
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+ PCI_BASE_CLASS_DISPLAY, 16, quirk_nvidia_hda);
+DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+ PCI_BASE_CLASS_DISPLAY, 16, quirk_nvidia_hda);
+
/*
* Some IDT switches incorrectly flag an ACS Source Validation error on
* completions for config read requests even though PCIe r4.0, sec
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 70e86148cb1e..66898463b81f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1336,6 +1336,7 @@
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS 0x0752
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS 0x07D8
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_320M 0x08A0
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS 0x0AA2
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA 0x0D85
--
2.20.1
next reply other threads:[~2019-06-13 16:43 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-13 6:35 Daniel Drake [this message]
2019-06-13 13:15 ` [PATCH] PCI: Expose hidden NVIDIA HDA controllers Ilia Mirkin
2019-06-13 19:25 ` Lukas Wunner
2019-06-13 19:44 ` Ilia Mirkin
2019-06-13 20:03 ` Bjorn Helgaas
2019-06-25 5:57 ` Daniel Drake
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190613063514.15317-1-drake@endlessm.com \
--to=drake@endlessm.com \
--cc=aplattner@nvidia.com \
--cc=bhelgaas@google.com \
--cc=hhfeuer@gmx.de \
--cc=imirkin@alum.mit.edu \
--cc=kherbst@redhat.com \
--cc=linux-pci@vger.kernel.org \
--cc=linux@endlessm.com \
--cc=lukas@wunner.de \
--cc=nouveau@lists.freedesktop.org \
--cc=peter@lekensteyn.nl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox