Message ID | 20230622205523.85375-25-terry.bowman@amd.com |
---|---|
State | Superseded |
Headers | show |
Series | cxl/pci: Add support for RCH RAS error handling | expand |
On 6/22/23 13:55, Terry Bowman wrote: > The RCH root port contains root command AER registers that should not be > enabled.[1] Disable these to prevent root port interrupts. > > [1] CXL 3.0 - 12.2.1.1 RCH Downstream Port-detected Errors > > Signed-off-by: Terry Bowman <terry.bowman@amd.com> > Signed-off-by: Robert Richter <rrichter@amd.com> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> > --- > drivers/cxl/core/core.h | 6 ++++++ > drivers/cxl/core/pci.c | 29 +++++++++++++++++++++++++++++ > drivers/cxl/core/port.c | 3 +++ > 3 files changed, 38 insertions(+) > > diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h > index 87467c633123..880bac9db376 100644 > --- a/drivers/cxl/core/core.h > +++ b/drivers/cxl/core/core.h > @@ -86,4 +86,10 @@ enum cxl_poison_trace_type { > CXL_POISON_TRACE_CLEAR, > }; > > +#ifdef CONFIG_PCIEAER_CXL > +void cxl_disable_rch_root_ints(struct cxl_dport *dport); > +#else > +static inline void cxl_disable_rch_root_ints(struct cxl_dport *dport) { }; > +#endif > + > #endif /* __CXL_CORE_H__ */ > diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c > index 9e0eba5ccfc4..897830c19d1a 100644 > --- a/drivers/cxl/core/pci.c > +++ b/drivers/cxl/core/pci.c > @@ -838,6 +838,35 @@ static void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds) > cxl_handle_rdport_ras(cxlds, dport); > } > > +void cxl_disable_rch_root_ints(struct cxl_dport *dport) > +{ > + void __iomem *aer_base = dport->regs.dport_aer; > + struct pci_host_bridge *bridge; > + u32 aer_cmd_mask, aer_cmd; > + > + if (!aer_base) > + return; > + > + bridge = to_pci_host_bridge(dport->dport_dev); > + > + /* > + * Disable RCH root port command interrupts. > + * CXL 3.0 12.2.1.1 - RCH Downstream Port-detected Errors > + * > + * This sequence may not be necessary. CXL spec states disabling > + * the root cmd register's interrupts is required. But, PCI spec > + * shows these are disabled by default on reset. > + */ > + if (bridge->native_cxl_error) { > + aer_cmd_mask = (PCI_ERR_ROOT_CMD_COR_EN | > + PCI_ERR_ROOT_CMD_NONFATAL_EN | > + PCI_ERR_ROOT_CMD_FATAL_EN); > + aer_cmd = readl(aer_base + PCI_ERR_ROOT_COMMAND); > + aer_cmd &= ~aer_cmd_mask; > + writel(aer_cmd, aer_base + PCI_ERR_ROOT_COMMAND); > + } > +} > + > #else > static void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds) { } > #endif > diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c > index a92794e6b7b4..2fdfb31f16c1 100644 > --- a/drivers/cxl/core/port.c > +++ b/drivers/cxl/core/port.c > @@ -1037,6 +1037,9 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, > > cxl_dport_map_regs(dport); > > + if (dport->rch) > + cxl_disable_rch_root_ints(dport); > + > cond_cxl_root_lock(port); > rc = add_dport(port, dport); > cond_cxl_root_unlock(port);
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 87467c633123..880bac9db376 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -86,4 +86,10 @@ enum cxl_poison_trace_type { CXL_POISON_TRACE_CLEAR, }; +#ifdef CONFIG_PCIEAER_CXL +void cxl_disable_rch_root_ints(struct cxl_dport *dport); +#else +static inline void cxl_disable_rch_root_ints(struct cxl_dport *dport) { }; +#endif + #endif /* __CXL_CORE_H__ */ diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c index 9e0eba5ccfc4..897830c19d1a 100644 --- a/drivers/cxl/core/pci.c +++ b/drivers/cxl/core/pci.c @@ -838,6 +838,35 @@ static void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds) cxl_handle_rdport_ras(cxlds, dport); } +void cxl_disable_rch_root_ints(struct cxl_dport *dport) +{ + void __iomem *aer_base = dport->regs.dport_aer; + struct pci_host_bridge *bridge; + u32 aer_cmd_mask, aer_cmd; + + if (!aer_base) + return; + + bridge = to_pci_host_bridge(dport->dport_dev); + + /* + * Disable RCH root port command interrupts. + * CXL 3.0 12.2.1.1 - RCH Downstream Port-detected Errors + * + * This sequence may not be necessary. CXL spec states disabling + * the root cmd register's interrupts is required. But, PCI spec + * shows these are disabled by default on reset. + */ + if (bridge->native_cxl_error) { + aer_cmd_mask = (PCI_ERR_ROOT_CMD_COR_EN | + PCI_ERR_ROOT_CMD_NONFATAL_EN | + PCI_ERR_ROOT_CMD_FATAL_EN); + aer_cmd = readl(aer_base + PCI_ERR_ROOT_COMMAND); + aer_cmd &= ~aer_cmd_mask; + writel(aer_cmd, aer_base + PCI_ERR_ROOT_COMMAND); + } +} + #else static void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds) { } #endif diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index a92794e6b7b4..2fdfb31f16c1 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -1037,6 +1037,9 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, cxl_dport_map_regs(dport); + if (dport->rch) + cxl_disable_rch_root_ints(dport); + cond_cxl_root_lock(port); rc = add_dport(port, dport); cond_cxl_root_unlock(port);