aboutsummaryrefslogtreecommitdiff
path: root/nixos/modules/kernel-patches/0019-PCI-aardvark-Add-support-for-AER-registers-on-emulat.patch
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/kernel-patches/0019-PCI-aardvark-Add-support-for-AER-registers-on-emulat.patch')
-rw-r--r--nixos/modules/kernel-patches/0019-PCI-aardvark-Add-support-for-AER-registers-on-emulat.patch139
1 files changed, 139 insertions, 0 deletions
diff --git a/nixos/modules/kernel-patches/0019-PCI-aardvark-Add-support-for-AER-registers-on-emulat.patch b/nixos/modules/kernel-patches/0019-PCI-aardvark-Add-support-for-AER-registers-on-emulat.patch
new file mode 100644
index 0000000..6a28e7f
--- /dev/null
+++ b/nixos/modules/kernel-patches/0019-PCI-aardvark-Add-support-for-AER-registers-on-emulat.patch
@@ -0,0 +1,139 @@
+From cbe67d3f1b2565b4d94ec08cbc2b144165cb9117 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Tue, 24 May 2022 15:28:26 +0200
+Subject: [PATCH 19/96] PCI: aardvark: Add support for AER registers on
+ emulated bridge
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Aardvark controller supports Advanced Error Reporting configuration
+registers.
+
+Export these registers on the emulated root bridge via new .read_ext() and
+.write_ext() methods.
+
+Note that in the Advanced Error Reporting Capability header the offset to
+the next Extended Capability header is set, but it is not documented in
+Armada 3700 Functional Specification. Since this change adds support only
+for Advanced Error Reporting, explicitly clear PCI_EXT_CAP_NEXT bits in AER
+capability header.
+
+Now the pcieport driver correctly detects AER support and allows PCIe AER
+driver to start receiving ERR interrupts. Kernel log now says:
+
+ pcieport 0000:00:00.0: AER: enabled with IRQ 52
+
+Link: https://lore.kernel.org/r/20220524132827.8837-2-kabel@kernel.org
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ drivers/pci/controller/pci-aardvark.c | 79 +++++++++++++++++++++++++++
+ 1 file changed, 79 insertions(+)
+
+diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
+index a97502b2aef1..4921d9cf80d2 100644
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -35,6 +35,7 @@
+ #define PCIE_CORE_DEV_REV_REG 0x8
+ #define PCIE_CORE_SSDEV_ID_REG 0x2c
+ #define PCIE_CORE_PCIEXP_CAP 0xc0
++#define PCIE_CORE_PCIERR_CAP 0x100
+ #define PCIE_CORE_ERR_CAPCTL_REG 0x118
+ #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5)
+ #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN BIT(6)
+@@ -943,11 +944,89 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
+ }
+ }
+
++static pci_bridge_emul_read_status_t
++advk_pci_bridge_emul_ext_conf_read(struct pci_bridge_emul *bridge,
++ int reg, u32 *value)
++{
++ struct advk_pcie *pcie = bridge->data;
++
++ switch (reg) {
++ case 0:
++ *value = advk_readl(pcie, PCIE_CORE_PCIERR_CAP + reg);
++
++ /*
++ * PCI_EXT_CAP_NEXT bits are set to offset 0x150, but Armada
++ * 3700 Functional Specification does not document registers
++ * at those addresses.
++ *
++ * Thus we clear PCI_EXT_CAP_NEXT bits to make Advanced Error
++ * Reporting Capability header the last Extended Capability.
++ * If we obtain documentation for those registers in the
++ * future, this can be changed.
++ */
++ *value &= 0x000fffff;
++ return PCI_BRIDGE_EMUL_HANDLED;
++
++ case PCI_ERR_UNCOR_STATUS:
++ case PCI_ERR_UNCOR_MASK:
++ case PCI_ERR_UNCOR_SEVER:
++ case PCI_ERR_COR_STATUS:
++ case PCI_ERR_COR_MASK:
++ case PCI_ERR_CAP:
++ case PCI_ERR_HEADER_LOG + 0:
++ case PCI_ERR_HEADER_LOG + 4:
++ case PCI_ERR_HEADER_LOG + 8:
++ case PCI_ERR_HEADER_LOG + 12:
++ case PCI_ERR_ROOT_COMMAND:
++ case PCI_ERR_ROOT_STATUS:
++ case PCI_ERR_ROOT_ERR_SRC:
++ *value = advk_readl(pcie, PCIE_CORE_PCIERR_CAP + reg);
++ return PCI_BRIDGE_EMUL_HANDLED;
++
++ default:
++ return PCI_BRIDGE_EMUL_NOT_HANDLED;
++ }
++}
++
++static void
++advk_pci_bridge_emul_ext_conf_write(struct pci_bridge_emul *bridge,
++ int reg, u32 old, u32 new, u32 mask)
++{
++ struct advk_pcie *pcie = bridge->data;
++
++ switch (reg) {
++ /* These are W1C registers, so clear other bits */
++ case PCI_ERR_UNCOR_STATUS:
++ case PCI_ERR_COR_STATUS:
++ case PCI_ERR_ROOT_STATUS:
++ new &= mask;
++ fallthrough;
++
++ case PCI_ERR_UNCOR_MASK:
++ case PCI_ERR_UNCOR_SEVER:
++ case PCI_ERR_COR_MASK:
++ case PCI_ERR_CAP:
++ case PCI_ERR_HEADER_LOG + 0:
++ case PCI_ERR_HEADER_LOG + 4:
++ case PCI_ERR_HEADER_LOG + 8:
++ case PCI_ERR_HEADER_LOG + 12:
++ case PCI_ERR_ROOT_COMMAND:
++ case PCI_ERR_ROOT_ERR_SRC:
++ advk_writel(pcie, new, PCIE_CORE_PCIERR_CAP + reg);
++ break;
++
++ default:
++ break;
++ }
++}
++
+ static const struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = {
+ .read_base = advk_pci_bridge_emul_base_conf_read,
+ .write_base = advk_pci_bridge_emul_base_conf_write,
+ .read_pcie = advk_pci_bridge_emul_pcie_conf_read,
+ .write_pcie = advk_pci_bridge_emul_pcie_conf_write,
++ .read_ext = advk_pci_bridge_emul_ext_conf_read,
++ .write_ext = advk_pci_bridge_emul_ext_conf_write,
+ };
+
+ /*
+--
+2.37.2
+