diff options
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.patch | 139 |
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 + |