From patchwork Mon Aug 14 08:20:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Minda Chen X-Patchwork-Id: 13352533 X-Patchwork-Delegate: kw@linux.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAA79C07E8B for ; Mon, 14 Aug 2023 08:21:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234547AbjHNIU5 (ORCPT ); Mon, 14 Aug 2023 04:20:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234707AbjHNIU1 (ORCPT ); Mon, 14 Aug 2023 04:20:27 -0400 Received: from ex01.ufhost.com (ex01.ufhost.com [61.152.239.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5FF33E6A; Mon, 14 Aug 2023 01:20:26 -0700 (PDT) Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id 0CD1124DCFA; Mon, 14 Aug 2023 16:20:25 +0800 (CST) Received: from EXMBX171.cuchost.com (172.16.6.91) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Mon, 14 Aug 2023 16:20:25 +0800 Received: from ubuntu.localdomain (183.27.98.20) by EXMBX171.cuchost.com (172.16.6.91) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Mon, 14 Aug 2023 16:20:23 +0800 From: Minda Chen To: Daire McNamara , Conor Dooley , Rob Herring , Krzysztof Kozlowski , Bjorn Helgaas , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84?= =?utf-8?q?ski?= , Emil Renner Berthing CC: , , , , =?utf-8?q?P?= =?utf-8?q?ali_Roh=C3=A1r?= , Paul Walmsley , Palmer Dabbelt , Albert Ou , Philipp Zabel , Mason Huo , Leyfoon Tan , Kevin Xie , Minda Chen Subject: [PATCH v3 06/11] PCI: plda: Add event interrupt codes and IRQ domain ops Date: Mon, 14 Aug 2023 16:20:11 +0800 Message-ID: <20230814082016.104181-7-minda.chen@starfivetech.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230814082016.104181-1-minda.chen@starfivetech.com> References: <20230814082016.104181-1-minda.chen@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [183.27.98.20] X-ClientProxiedBy: EXCAS062.cuchost.com (172.16.6.22) To EXMBX171.cuchost.com (172.16.6.91) X-YovoleRuleAgent: yovoleflag Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org For PolarFire implements non-PLDA local interrupt events, most of event interrupt process codes can not be re-used. PLDA implements new codes and IRQ domain ops like PolarFire. plda_handle_event adds a new IRQ num to event num mapping codes for PLDA local event except DMA engine interrupt events. The DMA engine interrupt events are implemented by vendors. Signed-off-by: Minda Chen --- .../pci/controller/plda/pcie-microchip-host.c | 29 +++--- drivers/pci/controller/plda/pcie-plda-host.c | 99 +++++++++++++++++++ drivers/pci/controller/plda/pcie-plda.h | 19 ++++ 3 files changed, 133 insertions(+), 14 deletions(-) diff --git a/drivers/pci/controller/plda/pcie-microchip-host.c b/drivers/pci/controller/plda/pcie-microchip-host.c index c28840315019..b42f1aac3ec3 100644 --- a/drivers/pci/controller/plda/pcie-microchip-host.c +++ b/drivers/pci/controller/plda/pcie-microchip-host.c @@ -96,20 +96,21 @@ #define EVENT_LOCAL_DMA_END_ENGINE_1 12 #define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13 #define EVENT_LOCAL_DMA_ERROR_ENGINE_1 14 -#define EVENT_LOCAL_A_ATR_EVT_POST_ERR 15 -#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR 16 -#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR 17 -#define EVENT_LOCAL_A_ATR_EVT_DOORBELL 18 -#define EVENT_LOCAL_P_ATR_EVT_POST_ERR 19 -#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR 20 -#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR 21 -#define EVENT_LOCAL_P_ATR_EVT_DOORBELL 22 -#define EVENT_LOCAL_PM_MSI_INT_INTX 23 -#define EVENT_LOCAL_PM_MSI_INT_MSI 24 -#define EVENT_LOCAL_PM_MSI_INT_AER_EVT 25 -#define EVENT_LOCAL_PM_MSI_INT_EVENTS 26 -#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR 27 -#define NUM_EVENTS 28 +#define NUM_MC_EVENTS 15 +#define EVENT_LOCAL_A_ATR_EVT_POST_ERR (NUM_MC_EVENTS + EVENT_A_ATR_EVT_POST_ERR) +#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + EVENT_A_ATR_EVT_FETCH_ERR) +#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + EVENT_A_ATR_EVT_DISCARD_ERR) +#define EVENT_LOCAL_A_ATR_EVT_DOORBELL (NUM_MC_EVENTS + EVENT_A_ATR_EVT_DOORBELL) +#define EVENT_LOCAL_P_ATR_EVT_POST_ERR (NUM_MC_EVENTS + EVENT_P_ATR_EVT_POST_ERR) +#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + EVENT_P_ATR_EVT_FETCH_ERR) +#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + EVENT_P_ATR_EVT_DISCARD_ERR) +#define EVENT_LOCAL_P_ATR_EVT_DOORBELL (NUM_MC_EVENTS + EVENT_P_ATR_EVT_DOORBELL) +#define EVENT_LOCAL_PM_MSI_INT_INTX (NUM_MC_EVENTS + EVENT_PM_MSI_INT_INTX) +#define EVENT_LOCAL_PM_MSI_INT_MSI (NUM_MC_EVENTS + EVENT_PM_MSI_INT_MSI) +#define EVENT_LOCAL_PM_MSI_INT_AER_EVT (NUM_MC_EVENTS + EVENT_PM_MSI_INT_AER_EVT) +#define EVENT_LOCAL_PM_MSI_INT_EVENTS (NUM_MC_EVENTS + EVENT_PM_MSI_INT_EVENTS) +#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR (NUM_MC_EVENTS + EVENT_PM_MSI_INT_SYS_ERR) +#define NUM_EVENTS (NUM_MC_EVENTS + NUM_PLDA_EVENTS) #define PCIE_EVENT_CAUSE(x, s) \ [EVENT_PCIE_ ## x] = { __stringify(x), s } diff --git a/drivers/pci/controller/plda/pcie-plda-host.c b/drivers/pci/controller/plda/pcie-plda-host.c index ce02cfe6b5fa..bf63f220a518 100644 --- a/drivers/pci/controller/plda/pcie-plda-host.c +++ b/drivers/pci/controller/plda/pcie-plda-host.c @@ -250,6 +250,105 @@ int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq, return 0; } +irqreturn_t plda_event_handler(int irq, void *dev_id) +{ + return IRQ_HANDLED; +} + +void plda_handle_event(struct irq_desc *desc) +{ + struct plda_pcie_rp *port = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned long events = 0; + u32 bit, val, origin; + + chained_irq_enter(chip, desc); + + val = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL); + origin = val; + val = val >> A_ATR_EVT_POST_ERR_SHIFT; + events |= val & 0xff; + if (origin & PM_MSI_INT_INTX_MASK) + events |= BIT(EVENT_PM_MSI_INT_INTX); + val = (origin >> PM_MSI_INT_MSI_SHIFT) & 0xf; + events |= val << EVENT_PM_MSI_INT_MSI; + + for_each_set_bit(bit, &events, port->num_events) + generic_handle_domain_irq(port->event_domain, bit); + + chained_irq_exit(chip, desc); +} + +static u32 plda_hwirq_to_mask(int hwirq) +{ + u32 mask; + + if (hwirq < EVENT_PM_MSI_INT_INTX) + mask = BIT(hwirq + A_ATR_EVT_POST_ERR_SHIFT); + else if (hwirq == EVENT_PM_MSI_INT_INTX) + mask = PM_MSI_INT_INTX_MASK; + else + mask = BIT(hwirq + PM_MSI_TO_MASK_OFFSET); + + return mask; +} + +static void plda_ack_event_irq(struct irq_data *data) +{ + struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data); + + writel_relaxed(plda_hwirq_to_mask(data->hwirq), + port->bridge_addr + ISTATUS_LOCAL); +} + +static void plda_mask_event_irq(struct irq_data *data) +{ + struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data); + u32 mask, val; + + mask = plda_hwirq_to_mask(data->hwirq); + + raw_spin_lock(&port->lock); + val = readl_relaxed(port->bridge_addr + IMASK_LOCAL); + val &= ~mask; + writel_relaxed(val, port->bridge_addr + IMASK_LOCAL); + raw_spin_unlock(&port->lock); +} + +static void plda_unmask_event_irq(struct irq_data *data) +{ + struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data); + u32 mask, val; + + mask = plda_hwirq_to_mask(data->hwirq); + + raw_spin_lock(&port->lock); + val = readl_relaxed(port->bridge_addr + IMASK_LOCAL); + val |= mask; + writel_relaxed(val, port->bridge_addr + IMASK_LOCAL); + raw_spin_unlock(&port->lock); +} + +static struct irq_chip plda_event_irq_chip = { + .name = "PLDA PCIe EVENT", + .irq_ack = plda_ack_event_irq, + .irq_mask = plda_mask_event_irq, + .irq_unmask = plda_unmask_event_irq, +}; + +static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq) +{ + irq_set_chip_and_handler(irq, &plda_event_irq_chip, handle_level_irq); + irq_set_chip_data(irq, domain->host_data); + + return 0; +} + +static const struct irq_domain_ops plda_evt_dom_ops = { + .map = plda_pcie_event_map, +}; + void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index, phys_addr_t axi_addr, phys_addr_t pci_addr, size_t size) diff --git a/drivers/pci/controller/plda/pcie-plda.h b/drivers/pci/controller/plda/pcie-plda.h index b4daa74a8812..56483ebb678d 100644 --- a/drivers/pci/controller/plda/pcie-plda.h +++ b/drivers/pci/controller/plda/pcie-plda.h @@ -90,6 +90,23 @@ /* PCIe Config space MSI capability structure */ #define MC_MSI_CAP_CTRL_OFFSET 0xe0u +#define EVENT_A_ATR_EVT_POST_ERR 0 +#define EVENT_A_ATR_EVT_FETCH_ERR 1 +#define EVENT_A_ATR_EVT_DISCARD_ERR 2 +#define EVENT_A_ATR_EVT_DOORBELL 3 +#define EVENT_P_ATR_EVT_POST_ERR 4 +#define EVENT_P_ATR_EVT_FETCH_ERR 5 +#define EVENT_P_ATR_EVT_DISCARD_ERR 6 +#define EVENT_P_ATR_EVT_DOORBELL 7 +#define EVENT_PM_MSI_INT_INTX 8 +#define EVENT_PM_MSI_INT_MSI 9 +#define EVENT_PM_MSI_INT_AER_EVT 10 +#define EVENT_PM_MSI_INT_EVENTS 11 +#define EVENT_PM_MSI_INT_SYS_ERR 12 +#define NUM_PLDA_EVENTS 13 + +#define PM_MSI_TO_MASK_OFFSET 19 + struct plda_msi { struct mutex lock; /* Protect used bitmap */ struct irq_domain *msi_domain; @@ -106,10 +123,12 @@ struct plda_pcie_rp { raw_spinlock_t lock; struct plda_msi msi; void __iomem *bridge_addr; + int num_events; }; void plda_handle_msi(struct irq_desc *desc); int plda_allocate_msi_domains(struct plda_pcie_rp *port); +irqreturn_t plda_event_handler(int irq, void *dev_id); void plda_handle_intx(struct irq_desc *desc); int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq);