From 080691d7b1af67205081dff5a7fc4a988e080981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Mon, 10 Jan 2022 02:12:45 +0100 Subject: kernel: 5.10: Backport pending pci-aardvark changes fixing MSI support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport Aardvark PCIe controller driver changes that fix MSI support, that were recently sent to the linux-pci mailing list [1]. These changes fix MSI and MSI-X support for this PCIe controller, which, among other things, make it possible to use NVMe drives with this PCIe controllers. [1] https://lore.kernel.org/linux-pci/20220110015018.26359-1-kabel@kernel.org/ Signed-off-by: Marek Behún --- ...k-Add-support-for-ERR-interrupt-on-emulat.patch | 105 +++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 target/linux/generic/pending-5.10/850-0013-PCI-aardvark-Add-support-for-ERR-interrupt-on-emulat.patch (limited to 'target/linux/generic/pending-5.10/850-0013-PCI-aardvark-Add-support-for-ERR-interrupt-on-emulat.patch') diff --git a/target/linux/generic/pending-5.10/850-0013-PCI-aardvark-Add-support-for-ERR-interrupt-on-emulat.patch b/target/linux/generic/pending-5.10/850-0013-PCI-aardvark-Add-support-for-ERR-interrupt-on-emulat.patch new file mode 100644 index 0000000000..9b15b7917e --- /dev/null +++ b/target/linux/generic/pending-5.10/850-0013-PCI-aardvark-Add-support-for-ERR-interrupt-on-emulat.patch @@ -0,0 +1,105 @@ +From 7f3e55a3890fa26d15e2e4e90213962d1a7f6df9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Fri, 12 Feb 2021 20:32:55 +0100 +Subject: [PATCH] PCI: aardvark: Add support for ERR interrupt on emulated + bridge +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +ERR interrupt is triggered when corresponding bit is unmasked in both ISR0 +and PCI_EXP_DEVCTL registers. Unmasking ERR bits in PCI_EXP_DEVCTL register +is not enough. This means that currently the ERR interrupt is never +triggered. + +Unmask ERR bits in ISR0 register at driver probe time. ERR interrupt is not +triggered until ERR bits are unmasked also in PCI_EXP_DEVCTL register, +which is done by AER driver. So it is safe to unconditionally unmask all +ERR bits in aardvark probe. + +Aardvark HW sets PCI_ERR_ROOT_AER_IRQ to zero and when corresponding bits +in ISR0 and PCI_EXP_DEVCTL are enabled, the HW triggers a generic interrupt +on GIC. Chain this interrupt to PCIe interrupt 0 with +generic_handle_domain_irq() to allow processing of ERR interrupts. + +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +--- + drivers/pci/controller/pci-aardvark.c | 36 ++++++++++++++++++++++++++- + 1 file changed, 35 insertions(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c +index e6cfee3b41a2..7956b103d3c7 100644 +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -97,6 +97,10 @@ + #define PCIE_MSG_PM_PME_MASK BIT(7) + #define PCIE_ISR0_MASK_REG (CONTROL_BASE_ADDR + 0x44) + #define PCIE_ISR0_MSI_INT_PENDING BIT(24) ++#define PCIE_ISR0_CORR_ERR BIT(11) ++#define PCIE_ISR0_NFAT_ERR BIT(12) ++#define PCIE_ISR0_FAT_ERR BIT(13) ++#define PCIE_ISR0_ERR_MASK GENMASK(13, 11) + #define PCIE_ISR0_INTX_ASSERT(val) BIT(16 + (val)) + #define PCIE_ISR0_INTX_DEASSERT(val) BIT(20 + (val)) + #define PCIE_ISR0_ALL_MASK GENMASK(31, 0) +@@ -785,11 +789,15 @@ advk_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge, + case PCI_INTERRUPT_LINE: { + /* + * From the whole 32bit register we support reading from HW only +- * one bit: PCI_BRIDGE_CTL_BUS_RESET. ++ * two bits: PCI_BRIDGE_CTL_BUS_RESET and PCI_BRIDGE_CTL_SERR. + * Other bits are retrieved only from emulated config buffer. + */ + __le32 *cfgspace = (__le32 *)&bridge->conf; + u32 val = le32_to_cpu(cfgspace[PCI_INTERRUPT_LINE / 4]); ++ if (advk_readl(pcie, PCIE_ISR0_MASK_REG) & PCIE_ISR0_ERR_MASK) ++ val &= ~(PCI_BRIDGE_CTL_SERR << 16); ++ else ++ val |= PCI_BRIDGE_CTL_SERR << 16; + if (advk_readl(pcie, PCIE_CORE_CTRL1_REG) & HOT_RESET_GEN) + val |= PCI_BRIDGE_CTL_BUS_RESET << 16; + else +@@ -815,6 +823,19 @@ advk_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, + break; + + case PCI_INTERRUPT_LINE: ++ /* ++ * According to Figure 6-3: Pseudo Logic Diagram for Error ++ * Message Controls in PCIe base specification, SERR# Enable bit ++ * in Bridge Control register enable receiving of ERR_* messages ++ */ ++ if (mask & (PCI_BRIDGE_CTL_SERR << 16)) { ++ u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG); ++ if (new & (PCI_BRIDGE_CTL_SERR << 16)) ++ val &= ~PCIE_ISR0_ERR_MASK; ++ else ++ val |= PCIE_ISR0_ERR_MASK; ++ advk_writel(pcie, val, PCIE_ISR0_MASK_REG); ++ } + if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) { + u32 val = advk_readl(pcie, PCIE_CORE_CTRL1_REG); + if (new & (PCI_BRIDGE_CTL_BUS_RESET << 16)) +@@ -1464,6 +1485,19 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie) + isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); + isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK); + ++ /* Process ERR interrupt */ ++ if (isr0_status & PCIE_ISR0_ERR_MASK) { ++ advk_writel(pcie, PCIE_ISR0_ERR_MASK, PCIE_ISR0_REG); ++ ++ /* ++ * Aardvark HW returns zero for PCI_ERR_ROOT_AER_IRQ, so use ++ * PCIe interrupt 0 ++ */ ++ virq = irq_find_mapping(pcie->irq_domain, 0); ++ if (generic_handle_irq(virq) == -EINVAL) ++ dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n"); ++ } ++ + /* Process MSI interrupts */ + if (isr0_status & PCIE_ISR0_MSI_INT_PENDING) + advk_pcie_handle_msi(pcie); +-- +2.34.1 + -- cgit v1.2.3