History

Merge branch 'pci/misc'

- Generalize multi-function power dependency device links (Abhishek Sahu) - Add NVIDIA GPU multi-function power dependencies (Abhishek Sahu) - Optimize /proc/bus/pci/devices by using seq_puts() instead of seq_printf() (Markus Elfring) - Enable NVIDIA HDA controllers if BIOS didn't (Lukas Wunner) * pci/misc: PCI: Enable NVIDIA HDA controllers PCI: Use seq_puts() instead of seq_printf() in show_device() PCI: Add NVIDIA GPU multi-function power dependencies PCI: Generalize multi-function power dependency device links

Bjorn Helgaas committed 7 years ago

Commit e0997722 parents 8cf80c5 b516ea53 files · +92 −21Browse files

Unified · Split

3 files
  1. drivers/pci/proc.c +1 −1
  2. drivers/pci/quirks.c +90 −20
  3. include/linux/pci_ids.h +1 −0
drivers/pci/proc.c+1−1
@@ -377,7 +377,7 @@ static int show_device(struct seq_file *m, void *v) · 376 unmodified lines
377 }377 }
378 seq_putc(m, '\t');378 seq_putc(m, '\t');
379 if (drv)379 if (drv)
380 seq_printf(m, "%s", drv->name);380 seq_puts(m, drv->name);
381 seq_putc(m, '\n');381 seq_putc(m, '\n');
382 return 0;382 return 0;
383}383}
drivers/pci/quirks.c+90−20
@@ -4934,35 +4934,49 @@ static void quirk_fsl_no_msi(struct pci_dev *pdev) · 4933 unmodified lines
4934DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_no_msi);4934DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_no_msi);
4935 4935
4936/*4936/*
4937 * GPUs with integrated HDA controller for streaming audio to attached displays4937 * Although not allowed by the spec, some multi-function devices have
4938 * need a device link from the HDA controller (consumer) to the GPU (supplier)4938 * dependencies of one function (consumer) on another (supplier). For the
4939 * so that the GPU is powered up whenever the HDA controller is accessed.4939 * consumer to work in D0, the supplier must also be in D0. Create a
4940 * The GPU and HDA controller are functions 0 and 1 of the same PCI device.4940 * device link from the consumer to the supplier to enforce this
4941 * The device link stays in place until shutdown (or removal of the PCI device4941 * dependency. Runtime PM is allowed by default on the consumer to prevent
4942 * if it's hotplugged). Runtime PM is allowed by default on the HDA controller4942 * it from permanently keeping the supplier awake.
4943 * to prevent it from permanently keeping the GPU awake.
4944 */4943 */
4945static void quirk_gpu_hda(struct pci_dev *hda)4944static void pci_create_device_link(struct pci_dev *pdev, unsigned int consumer,
4945 unsigned int supplier, unsigned int class,
4946 unsigned int class_shift)
4946{4947{
4947 struct pci_dev *gpu;4948 struct pci_dev *supplier_pdev;
4948 4949
4949 if (PCI_FUNC(hda->devfn) != 1)4950 if (PCI_FUNC(pdev->devfn) != consumer)
4950 return;4951 return;
4951 4952
4952 gpu = pci_get_domain_bus_and_slot(pci_domain_nr(hda->bus),4953 supplier_pdev = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
4953 hda->bus->number,4954 pdev->bus->number,
4954 PCI_DEVFN(PCI_SLOT(hda->devfn), 0));4955 PCI_DEVFN(PCI_SLOT(pdev->devfn), supplier));
4955 if (!gpu || (gpu->class >> 16) != PCI_BASE_CLASS_DISPLAY) {4956 if (!supplier_pdev || (supplier_pdev->class >> class_shift) != class) {
4956 pci_dev_put(gpu);4957 pci_dev_put(supplier_pdev);
4957 return;4958 return;
4958 }4959 }
4959 4960
4960 if (!device_link_add(&hda->dev, &gpu->dev,4961 if (device_link_add(&pdev->dev, &supplier_pdev->dev,
4961 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME))4962 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME))
4962 pci_err(hda, "cannot link HDA to GPU %s\n", pci_name(gpu));4963 pci_info(pdev, "D0 power state depends on %s\n",
4964 pci_name(supplier_pdev));
4965 else
4966 pci_err(pdev, "Cannot enforce power dependency on %s\n",
4967 pci_name(supplier_pdev));
4968
4969 pm_runtime_allow(&pdev->dev);
4970 pci_dev_put(supplier_pdev);
4971}
4963 4972
4964 pm_runtime_allow(&hda->dev);4973/*
4965 pci_dev_put(gpu);4974 * Create device link for GPUs with integrated HDA controller for streaming
4975 * audio to attached displays.
4976 */
4977static void quirk_gpu_hda(struct pci_dev *hda)
4978{
4979 pci_create_device_link(hda, 1, 0, PCI_BASE_CLASS_DISPLAY, 16);
4966}4980}
4967DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID,4981DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID,
4968 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);4982 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
@@ -4971,6 +4985,62 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_AMD, PCI_ANY_ID, · 2 unmodified lines
4971DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,4985DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
4972 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);4986 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
4973 4987
4988/*
4989 * Create device link for NVIDIA GPU with integrated USB xHCI Host
4990 * controller to VGA.
4991 */
4992static void quirk_gpu_usb(struct pci_dev *usb)
4993{
4994 pci_create_device_link(usb, 2, 0, PCI_BASE_CLASS_DISPLAY, 16);
4995}
4996DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
4997 PCI_CLASS_SERIAL_USB, 8, quirk_gpu_usb);
4998
4999/*
5000 * Create device link for NVIDIA GPU with integrated Type-C UCSI controller
5001 * to VGA. Currently there is no class code defined for UCSI device over PCI
5002 * so using UNKNOWN class for now and it will be updated when UCSI
5003 * over PCI gets a class code.
5004 */
5005#define PCI_CLASS_SERIAL_UNKNOWN 0x0c80
5006static void quirk_gpu_usb_typec_ucsi(struct pci_dev *ucsi)
5007{
5008 pci_create_device_link(ucsi, 3, 0, PCI_BASE_CLASS_DISPLAY, 16);
5009}
5010DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
5011 PCI_CLASS_SERIAL_UNKNOWN, 8,
5012 quirk_gpu_usb_typec_ucsi);
5013
5014/*
5015 * Enable the NVIDIA GPU integrated HDA controller if the BIOS left it
5016 * disabled. https://devtalk.nvidia.com/default/topic/1024022
5017 */
5018static 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}
5039DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
5040 PCI_BASE_CLASS_DISPLAY, 16, quirk_nvidia_hda);
5041DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
5042 PCI_BASE_CLASS_DISPLAY, 16, quirk_nvidia_hda);
5043
4974/*5044/*
4975 * Some IDT switches incorrectly flag an ACS Source Validation error on5045 * Some IDT switches incorrectly flag an ACS Source Validation error on
4976 * completions for config read requests even though PCIe r4.0, sec5046 * completions for config read requests even though PCIe r4.0, sec
include/linux/pci_ids.h+1−0
@@ -1336,6 +1336,7 @@ · 1335 unmodified lines
1336#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS 0x07521336#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS 0x0752
1337#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x07591337#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759
1338#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS 0x07D81338#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS 0x07D8
1339#define PCI_DEVICE_ID_NVIDIA_GEFORCE_320M 0x08A0
1339#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS 0x0AA21340#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS 0x0AA2
1340#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA 0x0D851341#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA 0x0D85
1341 1342

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t