diff options
Diffstat (limited to 'pkgs/patches-linux-5.15/0030-PCI-mvebu-Add-support-for-Advanced-Error-Reporting-r.patch')
-rw-r--r-- | pkgs/patches-linux-5.15/0030-PCI-mvebu-Add-support-for-Advanced-Error-Reporting-r.patch | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/pkgs/patches-linux-5.15/0030-PCI-mvebu-Add-support-for-Advanced-Error-Reporting-r.patch b/pkgs/patches-linux-5.15/0030-PCI-mvebu-Add-support-for-Advanced-Error-Reporting-r.patch new file mode 100644 index 0000000..fb806e5 --- /dev/null +++ b/pkgs/patches-linux-5.15/0030-PCI-mvebu-Add-support-for-Advanced-Error-Reporting-r.patch @@ -0,0 +1,125 @@ +From 6ccfcdf4eef16aaac2bddc3b625a2dabe357bcb1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Fri, 17 Sep 2021 13:46:44 +0200 +Subject: [PATCH 30/90] PCI: mvebu: Add support for Advanced Error Reporting + registers on emulated bridge +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +AER registers start at mvebu offset 0x0100. Registers PCI_ERR_ROOT_COMMAND, +PCI_ERR_ROOT_STATUS and PCI_ERR_ROOT_ERR_SRC are not supported on pre-XP +hardware and returns zeros. + +Note that AER interrupt is not supported yet as mvebu emulated bridge does +not implement interrupts support at all yet. + +Also remove custom macro PCIE_HEADER_LOG_4_OFF as it is unused and +correctly this register should be referenced via standard macros with +offset, e.g. as: PCIE_CAP_PCIERR_OFF + PCI_ERR_HEADER_LOG + 4. + +Signed-off-by: Pali Rohár <pali@kernel.org> +--- + drivers/pci/controller/pci-mvebu.c | 67 +++++++++++++++++++++++++++++- + 1 file changed, 66 insertions(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c +index 811af9e6ede5..9ea2f6a7c2b0 100644 +--- a/drivers/pci/controller/pci-mvebu.c ++++ b/drivers/pci/controller/pci-mvebu.c +@@ -34,7 +34,7 @@ + #define PCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3)) + #define PCIE_SSDEV_ID_OFF 0x002c + #define PCIE_CAP_PCIEXP 0x0060 +-#define PCIE_HEADER_LOG_4_OFF 0x0128 ++#define PCIE_CAP_PCIERR_OFF 0x0100 + #define PCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4)) + #define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4)) + #define PCIE_WIN04_BASE_OFF(n) (0x1824 + ((n) << 4)) +@@ -603,6 +603,37 @@ mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge, + return PCI_BRIDGE_EMUL_HANDLED; + } + ++static pci_bridge_emul_read_status_t ++mvebu_pci_bridge_emul_ext_conf_read(struct pci_bridge_emul *bridge, ++ int reg, u32 *value) ++{ ++ struct mvebu_pcie_port *port = bridge->data; ++ ++ switch (reg) { ++ case 0: ++ 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 = mvebu_readl(port, PCIE_CAP_PCIERR_OFF + reg); ++ break; ++ ++ default: ++ return PCI_BRIDGE_EMUL_NOT_HANDLED; ++ } ++ ++ return PCI_BRIDGE_EMUL_HANDLED; ++} ++ + static void + mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, + int reg, u32 old, u32 new, u32 mask) +@@ -715,11 +746,45 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge, + } + } + ++static void ++mvebu_pci_bridge_emul_ext_conf_write(struct pci_bridge_emul *bridge, ++ int reg, u32 old, u32 new, u32 mask) ++{ ++ struct mvebu_pcie_port *port = 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: ++ mvebu_writel(port, new, PCIE_CAP_PCIERR_OFF + reg); ++ break; ++ ++ default: ++ break; ++ } ++} ++ + static const struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = { + .read_base = mvebu_pci_bridge_emul_base_conf_read, + .write_base = mvebu_pci_bridge_emul_base_conf_write, + .read_pcie = mvebu_pci_bridge_emul_pcie_conf_read, + .write_pcie = mvebu_pci_bridge_emul_pcie_conf_write, ++ .read_ext = mvebu_pci_bridge_emul_ext_conf_read, ++ .write_ext = mvebu_pci_bridge_emul_ext_conf_write, + }; + + /* +-- +2.34.1 + |