110 lines
2.7 KiB
Diff
110 lines
2.7 KiB
Diff
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
|
|
--- a/arch/x86/pci/fixup.c
|
|
+++ b/arch/x86/pci/fixup.c
|
|
@@ -886,6 +886,105 @@ static void quirk_clear_strap_no_soft_reset_dev2_f0(struct pci_dev *dev)
|
|
}
|
|
}
|
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15b8, quirk_clear_strap_no_soft_reset_dev2_f0);
|
|
+
|
|
+/*
|
|
+ * Enhanced atomic operations can cause corruption with 64-bit IOVA
|
|
+ * on these devices.
|
|
+ */
|
|
+#define RX_ENH_ATOMIC_EN BIT(8)
|
|
+
|
|
+static const u32 nbio_7_7_pcie_smn_addrs[] = {
|
|
+ 0x111401d0,
|
|
+ 0x111411d0,
|
|
+ 0x111421d0,
|
|
+ 0x111431d0,
|
|
+ 0x111441d0,
|
|
+ 0x112401d0,
|
|
+ 0x112411d0,
|
|
+ 0x112421d0,
|
|
+ 0x112431d0,
|
|
+ 0x112441d0,
|
|
+ 0x112451d0,
|
|
+ 0x113401d0,
|
|
+ 0x114401d0,
|
|
+};
|
|
+
|
|
+static const u32 nbio_7_11_pcie_smn_addrs[] = {
|
|
+ 0x112401d0,
|
|
+ 0x112411d0,
|
|
+ 0x112421d0,
|
|
+ 0x112431d0,
|
|
+ 0x112441d0,
|
|
+ 0x112451d0,
|
|
+ 0x113401d0,
|
|
+ 0x113411d0,
|
|
+ 0x113421d0,
|
|
+ 0x113431d0,
|
|
+ 0x113441d0,
|
|
+ 0x113451d0,
|
|
+};
|
|
+
|
|
+static void quirk_amd_nbio_enhanced_atomic(struct pci_dev *host_bridge,
|
|
+ const u32 *smn_addrs,
|
|
+ size_t nr_smn_addrs)
|
|
+{
|
|
+ bool changed = false;
|
|
+ size_t i;
|
|
+ u32 data;
|
|
+ int ret;
|
|
+
|
|
+ for (i = 0; i < nr_smn_addrs; i++) {
|
|
+ ret = amd_smn_read(0, smn_addrs[i], &data);
|
|
+ if (ret)
|
|
+ continue;
|
|
+ if (!(data & RX_ENH_ATOMIC_EN))
|
|
+ continue;
|
|
+ data = data & ~RX_ENH_ATOMIC_EN;
|
|
+ ret = amd_smn_write(0, smn_addrs[i], data);
|
|
+ if (ret)
|
|
+ continue;
|
|
+ if (changed)
|
|
+ continue;
|
|
+ ret = amd_smn_read(0, smn_addrs[i], &data);
|
|
+ if (ret)
|
|
+ continue;
|
|
+ if (data & RX_ENH_ATOMIC_EN)
|
|
+ continue;
|
|
+ changed = true;
|
|
+ }
|
|
+
|
|
+ if (changed)
|
|
+ pci_info(host_bridge, "enhanced atomics disabled\n");
|
|
+}
|
|
+
|
|
+static void quirk_amd_nbio_7_7_disable_enhanced_atomic(struct pci_dev *dev)
|
|
+{
|
|
+ quirk_amd_nbio_enhanced_atomic(dev, nbio_7_7_pcie_smn_addrs,
|
|
+ ARRAY_SIZE(nbio_7_7_pcie_smn_addrs));
|
|
+}
|
|
+
|
|
+static void quirk_amd_nbio_7_11_disable_enhanced_atomic(struct pci_dev *dev)
|
|
+{
|
|
+ quirk_amd_nbio_enhanced_atomic(dev, nbio_7_11_pcie_smn_addrs,
|
|
+ ARRAY_SIZE(nbio_7_11_pcie_smn_addrs));
|
|
+}
|
|
+
|
|
+/* Phoenix, Hawk Point (NBIO 7.7) */
|
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x14E8,
|
|
+ quirk_amd_nbio_7_7_disable_enhanced_atomic);
|
|
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x14E8,
|
|
+ quirk_amd_nbio_7_7_disable_enhanced_atomic);
|
|
+
|
|
+/* Strix, Krackan, Strix Halo (NBIO 7.11) */
|
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1507,
|
|
+ quirk_amd_nbio_7_11_disable_enhanced_atomic);
|
|
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1507,
|
|
+ quirk_amd_nbio_7_11_disable_enhanced_atomic);
|
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1122,
|
|
+ quirk_amd_nbio_7_11_disable_enhanced_atomic);
|
|
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1122,
|
|
+ quirk_amd_nbio_7_11_disable_enhanced_atomic);
|
|
+
|
|
#endif
|
|
|
|
/*
|