Skip to content

Commit b516ea5

Browse files
l1kbjorn-helgaas
authored andcommitted
PCI: Enable NVIDIA HDA controllers
Many NVIDIA GPUs can be configured as either a single-function video device or a multi-function device with video at function 0 and an HDA audio controller at function 1. The HDA controller can be enabled or disabled by a bit in the function 0 config space. Some BIOSes leave the HDA disabled, which means the HDMI connector from the NVIDIA GPU may not work. Sometimes the BIOS enables the HDA if an HDMI cable is connected at boot time, but that doesn't handle hotplug cases. Enable the HDA controller on device enumeration and resume and re-read the header type, which tells us whether the GPU is a multi-function device. 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. See original post (URL below) for more details. This commit takes inspiration from an earlier patch by Daniel Drake. Link: https://lore.kernel.org/r/[email protected] v2 Link: https://lore.kernel.org/r/[email protected] v1 Link: https://devtalk.nvidia.com/default/topic/1024022 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75985 Signed-off-by: Lukas Wunner <[email protected]> Signed-off-by: Daniel Drake <[email protected]> [bhelgaas: commit log, log message, return early if already enabled] Signed-off-by: Bjorn Helgaas <[email protected]> Cc: Aaron Plattner <[email protected]> Cc: Peter Wu <[email protected]> Cc: Ilia Mirkin <[email protected]> Cc: Karol Herbst <[email protected]> Cc: Maik Freudenberg <[email protected]>
1 parent 590a18e commit b516ea5

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

drivers/pci/quirks.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5011,6 +5011,36 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
50115011
PCI_CLASS_SERIAL_UNKNOWN, 8,
50125012
quirk_gpu_usb_typec_ucsi);
50135013

5014+
/*
5015+
* Enable the NVIDIA GPU integrated HDA controller if the BIOS left it
5016+
* disabled. https://devtalk.nvidia.com/default/topic/1024022
5017+
*/
5018+
static void quirk_nvidia_hda(struct pci_dev *gpu)
5019+
{
5020+
u8 hdr_type;
5021+
u32 val;
5022+
5023+
/* There was no integrated HDA controller before MCP89 */
5024+
if (gpu->device < PCI_DEVICE_ID_NVIDIA_GEFORCE_320M)
5025+
return;
5026+
5027+
/* Bit 25 at offset 0x488 enables the HDA controller */
5028+
pci_read_config_dword(gpu, 0x488, &val);
5029+
if (val & BIT(25))
5030+
return;
5031+
5032+
pci_info(gpu, "Enabling HDA controller\n");
5033+
pci_write_config_dword(gpu, 0x488, val | BIT(25));
5034+
5035+
/* The GPU becomes a multi-function device when the HDA is enabled */
5036+
pci_read_config_byte(gpu, PCI_HEADER_TYPE, &hdr_type);
5037+
gpu->multifunction = !!(hdr_type & 0x80);
5038+
}
5039+
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
5040+
PCI_BASE_CLASS_DISPLAY, 16, quirk_nvidia_hda);
5041+
DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
5042+
PCI_BASE_CLASS_DISPLAY, 16, quirk_nvidia_hda);
5043+
50145044
/*
50155045
* Some IDT switches incorrectly flag an ACS Source Validation error on
50165046
* completions for config read requests even though PCIe r4.0, sec

include/linux/pci_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,7 @@
13361336
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS 0x0752
13371337
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759
13381338
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS 0x07D8
1339+
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_320M 0x08A0
13391340
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS 0x0AA2
13401341
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA 0x0D85
13411342

0 commit comments

Comments
 (0)