Skip to content

Commit ed7f4ba

Browse files
committed
NVIDIA: SAUCE: PCI: quirks: mirror PI7C9X3G606GPC Port 4 BAR0
Some Pericom/Diodes PI7C9X3G606GPC switches require downstream Port 4 BAR0 to mirror the upstream port BAR0. Firmware may apply this during boot, but Linux PCI resource assignment can move the upstream BAR0 and leave Port 4 without the required mirror. Add a final and resume quirk for downstream Port 4. The quirk verifies that the immediate upstream bridge is the same switch, then writes Port 4 BAR0 from the upstream BAR0 after resource assignment and after resume. Port 4 BAR0 may read back as zero even after a successful write, so the write must be validated by platform-specific means. BugLink: https://nvbugspro.nvidia.com/bug/6205517 BugLink: https://nvbugspro.nvidia.com/bug/6134331 Signed-off-by: Nirmoy Das <nirmoyd@nvidia.com> (cherry picked from commit 31881cf)
1 parent 704a746 commit ed7f4ba

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

drivers/pci/quirks.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6282,6 +6282,60 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_PERICOM, 0xb404,
62826282
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_PERICOM, 0xb404,
62836283
pci_fixup_pericom_acs_store_forward);
62846284

6285+
/*
6286+
* Some Pericom/Diodes PI7C9X3G606GPC switches require downstream Port 4
6287+
* BAR 0 to mirror the upstream port BAR 0. Firmware may program this
6288+
* during boot, but Linux resource assignment can move the upstream BAR.
6289+
* Re-apply the mirror after resource assignment and resume.
6290+
*/
6291+
static void pci_fixup_pericom_pi7c9x3g606gpc_msix_bar(struct pci_dev *pdev)
6292+
{
6293+
struct pci_dev *upstream;
6294+
u32 bar, upstream_bar;
6295+
6296+
if (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM)
6297+
return;
6298+
6299+
if (PCI_SLOT(pdev->devfn) != 4 || PCI_FUNC(pdev->devfn))
6300+
return;
6301+
6302+
upstream = pci_upstream_bridge(pdev);
6303+
if (!upstream || upstream->vendor != PCI_VENDOR_ID_PERICOM ||
6304+
upstream->device != PCI_DEVICE_ID_PERICOM_PI7C9X3G606GPC ||
6305+
pci_pcie_type(upstream) != PCI_EXP_TYPE_UPSTREAM)
6306+
return;
6307+
6308+
pci_read_config_dword(upstream, PCI_BASE_ADDRESS_0, &upstream_bar);
6309+
if (upstream_bar & PCI_BASE_ADDRESS_SPACE_IO)
6310+
return;
6311+
6312+
if ((upstream_bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
6313+
PCI_BASE_ADDRESS_MEM_TYPE_64) {
6314+
pci_warn(pdev, "skipping PI7C9X3G606GPC MSI-X BAR workaround for 64-bit upstream BAR 0\n");
6315+
return;
6316+
}
6317+
6318+
if (!(upstream_bar & PCI_BASE_ADDRESS_MEM_MASK)) {
6319+
pci_warn(pdev, "skipping PI7C9X3G606GPC MSI-X BAR workaround because upstream BAR 0 is unassigned\n");
6320+
return;
6321+
}
6322+
6323+
pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &bar);
6324+
if (bar == upstream_bar)
6325+
return;
6326+
6327+
/* Port 4 BAR 0 may read back as zero even after a successful write. */
6328+
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, upstream_bar);
6329+
pci_info(pdev, "wrote upstream BAR 0 %#x to Port 4 BAR 0 for PI7C9X3G606GPC workaround\n",
6330+
upstream_bar);
6331+
}
6332+
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_PERICOM,
6333+
PCI_DEVICE_ID_PERICOM_PI7C9X3G606GPC,
6334+
pci_fixup_pericom_pi7c9x3g606gpc_msix_bar);
6335+
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_PERICOM,
6336+
PCI_DEVICE_ID_PERICOM_PI7C9X3G606GPC,
6337+
pci_fixup_pericom_pi7c9x3g606gpc_msix_bar);
6338+
62856339
static void nvidia_ion_ahci_fixup(struct pci_dev *pdev)
62866340
{
62876341
pdev->dev_flags |= PCI_DEV_FLAGS_HAS_MSI_MASKING;

include/linux/pci_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,7 @@
18451845
#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
18461846

18471847
#define PCI_VENDOR_ID_PERICOM 0x12D8
1848+
#define PCI_DEVICE_ID_PERICOM_PI7C9X3G606GPC 0xc008
18481849
#define PCI_DEVICE_ID_PERICOM_PI7C9X7951 0x7951
18491850
#define PCI_DEVICE_ID_PERICOM_PI7C9X7952 0x7952
18501851
#define PCI_DEVICE_ID_PERICOM_PI7C9X7954 0x7954

0 commit comments

Comments
 (0)