mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-12 12:44:52 -04:00
PCI: mvebu: Add support for Advanced Error Reporting registers on emulated bridge
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. Link: https://lore.kernel.org/r/20220222155030.988-8-pali@kernel.org Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
This commit is contained in:
committed by
Lorenzo Pieralisi
parent
e3e13c9135
commit
2b6ee04c0a
@@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user