From patchwork Mon Jul 15 18:13:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mayank Rana X-Patchwork-Id: 13733784 X-Patchwork-Delegate: manivannanece23@gmail.com Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A27526BFA6; Mon, 15 Jul 2024 18:14:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067296; cv=none; b=h4yN8F8BT1YoFxFody79ya0xh132CpdNS2Btyt+zzroNLQQUHsLj2FzKeTQzVKR/VSLS576X6LH8deGkqP6xuDpTkuEmtNZWNLoA/VAssa7wHdF/194+hNkYU1YKS/aIjuQK0VmxanojIDiTya5JZ5jMSw2jNW54+hKkVRBhToc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067296; c=relaxed/simple; bh=eukdmm2ARZSzGfpl7TWM/KvMFFl0gfAb67WYEUP3Nok=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pTbjCbjuOxXCdVzWtfwBxYL7Y1pGVejuz/rCe/BPVbFPwsiJpNRveJxl9DZRV5ojYVBPdr28cRowENWAMhE88NEjeXK1laaACCpLNrtfmf/dJ7A2OVugBrT9ridXfunD7zjGa4nwodDZgfUcAqfIpZYMyweA/DZJQXZC48tAk4o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=ih8OWQsk; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="ih8OWQsk" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46FH8huT004035; Mon, 15 Jul 2024 18:13:54 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=XjvE6+jp3bswpcSq3W90XcPf 2y+syK5804kEk52YpvQ=; b=ih8OWQskGjK2fGObuggBNGl+MyZO3tGLi/vWSMzB +6To1xKfgmIR76gl7Wgmz5/agMOfoI+UFIZDD33KpCf2xNBkNjd4M9rtO0HgYhxV 8h98MEt7EpGtXrElaagQbux9Xw4HTxS80uDrWgZ53Zr+Bl79j8Q3ijuLEpvdbll0 XRBVlH5IhfFZtR5mrzByQzNmXIod5KqhjS/sLOgp5HX2oitnyd+6zbJR6tYBFt5z CYLzjjz9OU0zibM7oXEsDAzsViojOfwm+DqOKeJO5G7iMZm4Ha/KV4HMkNvGiRRb 28m13b82BwV1ajz06hCYJsjqX6+K6Q7GY/QkZgKpIJGwHg== Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40bghrn1u3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:53 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA01.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 46FIDqGq026337 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:52 GMT Received: from hu-mrana-lv.qualcomm.com (10.49.16.6) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Mon, 15 Jul 2024 11:13:51 -0700 From: Mayank Rana To: , , , , , , , , , , , , , , , , , , , , , , , CC: , , , , , Mayank Rana Subject: [PATCH V2 1/7] PCI: dwc: Move MSI functionality related code to separate file Date: Mon, 15 Jul 2024 11:13:29 -0700 Message-ID: <1721067215-5832-2-git-send-email-quic_mrana@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> References: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nalasex01c.na.qualcomm.com (10.47.97.35) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: jIXMk_IjjS4TtoMbvy1nkdrrN0zCZJTp X-Proofpoint-ORIG-GUID: jIXMk_IjjS4TtoMbvy1nkdrrN0zCZJTp X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-15_12,2024-07-11_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 phishscore=0 clxscore=1015 malwarescore=0 spamscore=0 suspectscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 impostorscore=0 adultscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2406140001 definitions=main-2407150142 This change moves dwc PCIe controller specific MSI functionality into separate file in preparation to allow MSI functionality with PCIe ECAM driver. Update existing drivers to accommodate this change. Signed-off-by: Mayank Rana --- drivers/pci/controller/dwc/Makefile | 2 +- drivers/pci/controller/dwc/pci-keystone.c | 12 +- drivers/pci/controller/dwc/pcie-designware-host.c | 420 +--------------------- drivers/pci/controller/dwc/pcie-designware-msi.c | 409 +++++++++++++++++++++ drivers/pci/controller/dwc/pcie-designware-msi.h | 43 +++ drivers/pci/controller/dwc/pcie-designware.c | 1 + drivers/pci/controller/dwc/pcie-designware.h | 26 +- drivers/pci/controller/dwc/pcie-rcar-gen4.c | 1 + drivers/pci/controller/dwc/pcie-tegra194.c | 5 +- 9 files changed, 484 insertions(+), 435 deletions(-) create mode 100644 drivers/pci/controller/dwc/pcie-designware-msi.c create mode 100644 drivers/pci/controller/dwc/pcie-designware-msi.h diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile index bac103f..2ecc603 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PCIE_DW) += pcie-designware.o -obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o +obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o pcie-designware-msi.o obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index cd0e002..b95d319 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -307,8 +307,14 @@ static int ks_pcie_msi_host_init(struct dw_pcie_rp *pp) */ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, ks_pcie->app.start); - pp->msi_irq_chip = &ks_pcie_msi_irq_chip; - return dw_pcie_allocate_domains(pp); + pp->msi = devm_kzalloc(pci->dev, sizeof(struct dw_msi *), GFP_KERNEL); + if (pp->msi == NULL) + return -ENOMEM; + + pp->msi->msi_irq_chip = &ks_pcie_msi_irq_chip; + pp->msi->dev = pci->dev; + pp->msi->private_data = pp; + return dw_pcie_allocate_domains(pp->msi); } static void ks_pcie_handle_intx_irq(struct keystone_pcie *ks_pcie, @@ -322,7 +328,7 @@ static void ks_pcie_handle_intx_irq(struct keystone_pcie *ks_pcie, if (BIT(0) & pending) { dev_dbg(dev, ": irq: irq_offset %d", offset); - generic_handle_domain_irq(ks_pcie->intx_irq_domain, offset); + generic_handle_domain_irq(ks_pcie->msi->intx_irq_domain, offset); } /* EOI the INTx interrupt */ diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index a0822d5..3dcf88a 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -9,9 +9,6 @@ */ #include -#include -#include -#include #include #include #include @@ -19,385 +16,11 @@ #include "../../pci.h" #include "pcie-designware.h" +#include "pcie-designware-msi.h" static struct pci_ops dw_pcie_ops; static struct pci_ops dw_child_pcie_ops; -static void dw_msi_ack_irq(struct irq_data *d) -{ - irq_chip_ack_parent(d); -} - -static void dw_msi_mask_irq(struct irq_data *d) -{ - pci_msi_mask_irq(d); - irq_chip_mask_parent(d); -} - -static void dw_msi_unmask_irq(struct irq_data *d) -{ - pci_msi_unmask_irq(d); - irq_chip_unmask_parent(d); -} - -static struct irq_chip dw_pcie_msi_irq_chip = { - .name = "PCI-MSI", - .irq_ack = dw_msi_ack_irq, - .irq_mask = dw_msi_mask_irq, - .irq_unmask = dw_msi_unmask_irq, -}; - -static struct msi_domain_info dw_pcie_msi_domain_info = { - .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | - MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), - .chip = &dw_pcie_msi_irq_chip, -}; - -/* MSI int handler */ -irqreturn_t dw_handle_msi_irq(struct dw_pcie_rp *pp) -{ - int i, pos; - unsigned long val; - u32 status, num_ctrls; - irqreturn_t ret = IRQ_NONE; - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - - num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; - - for (i = 0; i < num_ctrls; i++) { - status = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS + - (i * MSI_REG_CTRL_BLOCK_SIZE)); - if (!status) - continue; - - ret = IRQ_HANDLED; - val = status; - pos = 0; - while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, - pos)) != MAX_MSI_IRQS_PER_CTRL) { - generic_handle_domain_irq(pp->irq_domain, - (i * MAX_MSI_IRQS_PER_CTRL) + - pos); - pos++; - } - } - - return ret; -} - -/* Chained MSI interrupt service routine */ -static void dw_chained_msi_isr(struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - struct dw_pcie_rp *pp; - - chained_irq_enter(chip, desc); - - pp = irq_desc_get_handler_data(desc); - dw_handle_msi_irq(pp); - - chained_irq_exit(chip, desc); -} - -static void dw_pci_setup_msi_msg(struct irq_data *d, struct msi_msg *msg) -{ - struct dw_pcie_rp *pp = irq_data_get_irq_chip_data(d); - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - u64 msi_target; - - msi_target = (u64)pp->msi_data; - - msg->address_lo = lower_32_bits(msi_target); - msg->address_hi = upper_32_bits(msi_target); - - msg->data = d->hwirq; - - dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", - (int)d->hwirq, msg->address_hi, msg->address_lo); -} - -static int dw_pci_msi_set_affinity(struct irq_data *d, - const struct cpumask *mask, bool force) -{ - return -EINVAL; -} - -static void dw_pci_bottom_mask(struct irq_data *d) -{ - struct dw_pcie_rp *pp = irq_data_get_irq_chip_data(d); - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - unsigned int res, bit, ctrl; - unsigned long flags; - - raw_spin_lock_irqsave(&pp->lock, flags); - - ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; - res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; - bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; - - pp->irq_mask[ctrl] |= BIT(bit); - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, pp->irq_mask[ctrl]); - - raw_spin_unlock_irqrestore(&pp->lock, flags); -} - -static void dw_pci_bottom_unmask(struct irq_data *d) -{ - struct dw_pcie_rp *pp = irq_data_get_irq_chip_data(d); - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - unsigned int res, bit, ctrl; - unsigned long flags; - - raw_spin_lock_irqsave(&pp->lock, flags); - - ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; - res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; - bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; - - pp->irq_mask[ctrl] &= ~BIT(bit); - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, pp->irq_mask[ctrl]); - - raw_spin_unlock_irqrestore(&pp->lock, flags); -} - -static void dw_pci_bottom_ack(struct irq_data *d) -{ - struct dw_pcie_rp *pp = irq_data_get_irq_chip_data(d); - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - unsigned int res, bit, ctrl; - - ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; - res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; - bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; - - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_STATUS + res, BIT(bit)); -} - -static struct irq_chip dw_pci_msi_bottom_irq_chip = { - .name = "DWPCI-MSI", - .irq_ack = dw_pci_bottom_ack, - .irq_compose_msi_msg = dw_pci_setup_msi_msg, - .irq_set_affinity = dw_pci_msi_set_affinity, - .irq_mask = dw_pci_bottom_mask, - .irq_unmask = dw_pci_bottom_unmask, -}; - -static int dw_pcie_irq_domain_alloc(struct irq_domain *domain, - unsigned int virq, unsigned int nr_irqs, - void *args) -{ - struct dw_pcie_rp *pp = domain->host_data; - unsigned long flags; - u32 i; - int bit; - - raw_spin_lock_irqsave(&pp->lock, flags); - - bit = bitmap_find_free_region(pp->msi_irq_in_use, pp->num_vectors, - order_base_2(nr_irqs)); - - raw_spin_unlock_irqrestore(&pp->lock, flags); - - if (bit < 0) - return -ENOSPC; - - for (i = 0; i < nr_irqs; i++) - irq_domain_set_info(domain, virq + i, bit + i, - pp->msi_irq_chip, - pp, handle_edge_irq, - NULL, NULL); - - return 0; -} - -static void dw_pcie_irq_domain_free(struct irq_domain *domain, - unsigned int virq, unsigned int nr_irqs) -{ - struct irq_data *d = irq_domain_get_irq_data(domain, virq); - struct dw_pcie_rp *pp = domain->host_data; - unsigned long flags; - - raw_spin_lock_irqsave(&pp->lock, flags); - - bitmap_release_region(pp->msi_irq_in_use, d->hwirq, - order_base_2(nr_irqs)); - - raw_spin_unlock_irqrestore(&pp->lock, flags); -} - -static const struct irq_domain_ops dw_pcie_msi_domain_ops = { - .alloc = dw_pcie_irq_domain_alloc, - .free = dw_pcie_irq_domain_free, -}; - -int dw_pcie_allocate_domains(struct dw_pcie_rp *pp) -{ - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - struct fwnode_handle *fwnode = of_node_to_fwnode(pci->dev->of_node); - - pp->irq_domain = irq_domain_create_linear(fwnode, pp->num_vectors, - &dw_pcie_msi_domain_ops, pp); - if (!pp->irq_domain) { - dev_err(pci->dev, "Failed to create IRQ domain\n"); - return -ENOMEM; - } - - irq_domain_update_bus_token(pp->irq_domain, DOMAIN_BUS_NEXUS); - - pp->msi_domain = pci_msi_create_irq_domain(fwnode, - &dw_pcie_msi_domain_info, - pp->irq_domain); - if (!pp->msi_domain) { - dev_err(pci->dev, "Failed to create MSI domain\n"); - irq_domain_remove(pp->irq_domain); - return -ENOMEM; - } - - return 0; -} - -static void dw_pcie_free_msi(struct dw_pcie_rp *pp) -{ - u32 ctrl; - - for (ctrl = 0; ctrl < MAX_MSI_CTRLS; ctrl++) { - if (pp->msi_irq[ctrl] > 0) - irq_set_chained_handler_and_data(pp->msi_irq[ctrl], - NULL, NULL); - } - - irq_domain_remove(pp->msi_domain); - irq_domain_remove(pp->irq_domain); -} - -static void dw_pcie_msi_init(struct dw_pcie_rp *pp) -{ - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - u64 msi_target = (u64)pp->msi_data; - - if (!pci_msi_enabled() || !pp->has_msi_ctrl) - return; - - /* Program the msi_data */ - dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_LO, lower_32_bits(msi_target)); - dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_HI, upper_32_bits(msi_target)); -} - -static int dw_pcie_parse_split_msi_irq(struct dw_pcie_rp *pp) -{ - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - struct device *dev = pci->dev; - struct platform_device *pdev = to_platform_device(dev); - u32 ctrl, max_vectors; - int irq; - - /* Parse any "msiX" IRQs described in the devicetree */ - for (ctrl = 0; ctrl < MAX_MSI_CTRLS; ctrl++) { - char msi_name[] = "msiX"; - - msi_name[3] = '0' + ctrl; - irq = platform_get_irq_byname_optional(pdev, msi_name); - if (irq == -ENXIO) - break; - if (irq < 0) - return dev_err_probe(dev, irq, - "Failed to parse MSI IRQ '%s'\n", - msi_name); - - pp->msi_irq[ctrl] = irq; - } - - /* If no "msiX" IRQs, caller should fallback to "msi" IRQ */ - if (ctrl == 0) - return -ENXIO; - - max_vectors = ctrl * MAX_MSI_IRQS_PER_CTRL; - if (pp->num_vectors > max_vectors) { - dev_warn(dev, "Exceeding number of MSI vectors, limiting to %u\n", - max_vectors); - pp->num_vectors = max_vectors; - } - if (!pp->num_vectors) - pp->num_vectors = max_vectors; - - return 0; -} - -static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp) -{ - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - struct device *dev = pci->dev; - struct platform_device *pdev = to_platform_device(dev); - u64 *msi_vaddr = NULL; - int ret; - u32 ctrl, num_ctrls; - - for (ctrl = 0; ctrl < MAX_MSI_CTRLS; ctrl++) - pp->irq_mask[ctrl] = ~0; - - if (!pp->msi_irq[0]) { - ret = dw_pcie_parse_split_msi_irq(pp); - if (ret < 0 && ret != -ENXIO) - return ret; - } - - if (!pp->num_vectors) - pp->num_vectors = MSI_DEF_NUM_VECTORS; - num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; - - if (!pp->msi_irq[0]) { - pp->msi_irq[0] = platform_get_irq_byname_optional(pdev, "msi"); - if (pp->msi_irq[0] < 0) { - pp->msi_irq[0] = platform_get_irq(pdev, 0); - if (pp->msi_irq[0] < 0) - return pp->msi_irq[0]; - } - } - - dev_dbg(dev, "Using %d MSI vectors\n", pp->num_vectors); - - pp->msi_irq_chip = &dw_pci_msi_bottom_irq_chip; - - ret = dw_pcie_allocate_domains(pp); - if (ret) - return ret; - - for (ctrl = 0; ctrl < num_ctrls; ctrl++) { - if (pp->msi_irq[ctrl] > 0) - irq_set_chained_handler_and_data(pp->msi_irq[ctrl], - dw_chained_msi_isr, pp); - } - - /* - * Even though the iMSI-RX Module supports 64-bit addresses some - * peripheral PCIe devices may lack 64-bit message support. In - * order not to miss MSI TLPs from those devices the MSI target - * address has to be within the lowest 4GB. - * - * Note until there is a better alternative found the reservation is - * done by allocating from the artificially limited DMA-coherent - * memory. - */ - ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); - if (!ret) - msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data, - GFP_KERNEL); - - if (!msi_vaddr) { - dev_warn(dev, "Failed to allocate 32-bit MSI address\n"); - dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); - msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data, - GFP_KERNEL); - if (!msi_vaddr) { - dev_err(dev, "Failed to allocate MSI address\n"); - dw_pcie_free_msi(pp); - return -ENOMEM; - } - } - - return 0; -} - static void dw_pcie_host_request_msg_tlp_res(struct dw_pcie_rp *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -433,6 +56,7 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) struct resource_entry *win; struct pci_host_bridge *bridge; struct resource *res; + bool has_msi_ctrl; int ret; raw_spin_lock_init(&pp->lock); @@ -479,15 +103,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) } if (pci_msi_enabled()) { - pp->has_msi_ctrl = !(pp->ops->msi_init || - of_property_read_bool(np, "msi-parent") || - of_property_read_bool(np, "msi-map")); + has_msi_ctrl = !(pp->ops->msi_init || + of_property_read_bool(np, "msi-parent") || + of_property_read_bool(np, "msi-map")); /* * For the has_msi_ctrl case the default assignment is handled * in the dw_pcie_msi_host_init(). */ - if (!pp->has_msi_ctrl && !pp->num_vectors) { + if (!has_msi_ctrl && !pp->num_vectors) { pp->num_vectors = MSI_DEF_NUM_VECTORS; } else if (pp->num_vectors > MAX_MSI_IRQS) { dev_err(dev, "Invalid number of vectors\n"); @@ -499,10 +123,12 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) ret = pp->ops->msi_init(pp); if (ret < 0) goto err_deinit_host; - } else if (pp->has_msi_ctrl) { - ret = dw_pcie_msi_host_init(pp); - if (ret < 0) + } else if (has_msi_ctrl) { + pp->msi = dw_pcie_msi_host_init(pdev, pp, pp->num_vectors); + if (IS_ERR(pp->msi)) { + ret = PTR_ERR(pp->msi); goto err_deinit_host; + } } } @@ -557,8 +183,7 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) dw_pcie_edma_remove(pci); err_free_msi: - if (pp->has_msi_ctrl) - dw_pcie_free_msi(pp); + dw_pcie_free_msi(pp->msi); err_deinit_host: if (pp->ops->deinit) @@ -579,8 +204,7 @@ void dw_pcie_host_deinit(struct dw_pcie_rp *pp) dw_pcie_edma_remove(pci); - if (pp->has_msi_ctrl) - dw_pcie_free_msi(pp); + dw_pcie_free_msi(pp->msi); if (pp->ops->deinit) pp->ops->deinit(pp); @@ -808,7 +432,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp) int dw_pcie_setup_rc(struct dw_pcie_rp *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - u32 val, ctrl, num_ctrls; + u32 val; int ret; /* @@ -819,21 +443,7 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp) dw_pcie_setup(pci); - if (pp->has_msi_ctrl) { - num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; - - /* Initialize IRQ Status array */ - for (ctrl = 0; ctrl < num_ctrls; ctrl++) { - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + - (ctrl * MSI_REG_CTRL_BLOCK_SIZE), - pp->irq_mask[ctrl]); - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_ENABLE + - (ctrl * MSI_REG_CTRL_BLOCK_SIZE), - ~0); - } - } - - dw_pcie_msi_init(pp); + dw_pcie_msi_init(pp->msi); /* Setup RC BARs */ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004); diff --git a/drivers/pci/controller/dwc/pcie-designware-msi.c b/drivers/pci/controller/dwc/pcie-designware-msi.c new file mode 100644 index 0000000..39fe5be --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-designware-msi.c @@ -0,0 +1,409 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * https://www.samsung.com + * + * Author: Jingoo Han + */ + +#include +#include +#include +#include + +#include "pcie-designware.h" +#include "pcie-designware-msi.h" + +static void dw_msi_ack_irq(struct irq_data *d) +{ + irq_chip_ack_parent(d); +} + +static void dw_msi_mask_irq(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} + +static void dw_msi_unmask_irq(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} + +static struct irq_chip dw_pcie_msi_irq_chip = { + .name = "PCI-MSI", + .irq_ack = dw_msi_ack_irq, + .irq_mask = dw_msi_mask_irq, + .irq_unmask = dw_msi_unmask_irq, +}; + +static struct msi_domain_info dw_pcie_msi_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), + .chip = &dw_pcie_msi_irq_chip, +}; + +/* MSI int handler */ +irqreturn_t dw_handle_msi_irq(struct dw_msi *msi) +{ + int i, pos; + unsigned long val; + u32 status, num_ctrls; + irqreturn_t ret = IRQ_NONE; + struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); + + num_ctrls = msi->num_vectors / MAX_MSI_IRQS_PER_CTRL; + + for (i = 0; i < num_ctrls; i++) { + status = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS + + (i * MSI_REG_CTRL_BLOCK_SIZE)); + if (!status) + continue; + + ret = IRQ_HANDLED; + val = status; + pos = 0; + while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, + pos)) != MAX_MSI_IRQS_PER_CTRL) { + generic_handle_domain_irq(msi->irq_domain, + (i * MAX_MSI_IRQS_PER_CTRL) + + pos); + pos++; + } + } + + return ret; +} + +/* Chained MSI interrupt service routine */ +static void dw_chained_msi_isr(struct irq_desc *desc) +{ + struct irq_chip *chip = irq_desc_get_chip(desc); + struct dw_msi *msi; + + chained_irq_enter(chip, desc); + + msi = irq_desc_get_handler_data(desc); + dw_handle_msi_irq(msi); + + chained_irq_exit(chip, desc); +} + +static void dw_pci_setup_msi_msg(struct irq_data *d, struct msi_msg *msg) +{ + struct dw_msi *msi = irq_data_get_irq_chip_data(d); + u64 msi_target; + + msi_target = (u64)msi->msi_data; + + msg->address_lo = lower_32_bits(msi_target); + msg->address_hi = upper_32_bits(msi_target); + + msg->data = d->hwirq; + + dev_dbg(msi->dev, "msi#%d address_hi %#x address_lo %#x\n", + (int)d->hwirq, msg->address_hi, msg->address_lo); +} + +static int dw_pci_msi_set_affinity(struct irq_data *d, + const struct cpumask *mask, bool force) +{ + return -EINVAL; +} + +static void dw_pci_bottom_mask(struct irq_data *d) +{ + struct dw_msi *msi = irq_data_get_irq_chip_data(d); + struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); + unsigned int res, bit, ctrl; + unsigned long flags; + + raw_spin_lock_irqsave(&msi->lock, flags); + + ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; + res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; + bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; + + msi->irq_mask[ctrl] |= BIT(bit); + dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, msi->irq_mask[ctrl]); + + raw_spin_unlock_irqrestore(&msi->lock, flags); +} + +static void dw_pci_bottom_unmask(struct irq_data *d) +{ + struct dw_msi *msi = irq_data_get_irq_chip_data(d); + struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); + unsigned int res, bit, ctrl; + unsigned long flags; + + raw_spin_lock_irqsave(&msi->lock, flags); + + ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; + res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; + bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; + + msi->irq_mask[ctrl] &= ~BIT(bit); + dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, msi->irq_mask[ctrl]); + + raw_spin_unlock_irqrestore(&msi->lock, flags); +} + +static void dw_pci_bottom_ack(struct irq_data *d) +{ + struct dw_msi *msi = irq_data_get_irq_chip_data(d); + struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); + unsigned int res, bit, ctrl; + + ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; + res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; + bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; + + dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_STATUS + res, BIT(bit)); +} + +static struct irq_chip dw_pci_msi_bottom_irq_chip = { + .name = "DWPCI-MSI", + .irq_ack = dw_pci_bottom_ack, + .irq_compose_msi_msg = dw_pci_setup_msi_msg, + .irq_set_affinity = dw_pci_msi_set_affinity, + .irq_mask = dw_pci_bottom_mask, + .irq_unmask = dw_pci_bottom_unmask, +}; + +static int dw_pcie_irq_domain_alloc(struct irq_domain *domain, + unsigned int virq, unsigned int nr_irqs, + void *args) +{ + struct dw_msi *msi = domain->host_data; + unsigned long flags; + u32 i; + int bit; + + raw_spin_lock_irqsave(&msi->lock, flags); + + bit = bitmap_find_free_region(msi->msi_irq_in_use, msi->num_vectors, + order_base_2(nr_irqs)); + + raw_spin_unlock_irqrestore(&msi->lock, flags); + + if (bit < 0) + return -ENOSPC; + + for (i = 0; i < nr_irqs; i++) + irq_domain_set_info(domain, virq + i, bit + i, + msi->msi_irq_chip, + msi, handle_edge_irq, + NULL, NULL); + + return 0; +} + +static void dw_pcie_irq_domain_free(struct irq_domain *domain, + unsigned int virq, unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct dw_msi *msi = domain->host_data; + unsigned long flags; + + raw_spin_lock_irqsave(&msi->lock, flags); + + bitmap_release_region(msi->msi_irq_in_use, d->hwirq, + order_base_2(nr_irqs)); + + raw_spin_unlock_irqrestore(&msi->lock, flags); +} + +static const struct irq_domain_ops dw_pcie_msi_domain_ops = { + .alloc = dw_pcie_irq_domain_alloc, + .free = dw_pcie_irq_domain_free, +}; + +int dw_pcie_allocate_domains(struct dw_msi *msi) +{ + struct fwnode_handle *fwnode = of_node_to_fwnode(msi->dev->of_node); + + msi->irq_domain = irq_domain_create_linear(fwnode, msi->num_vectors, + &dw_pcie_msi_domain_ops, + msi->private_data ? msi->private_data : msi); + if (!msi->irq_domain) { + dev_err(msi->dev, "Failed to create IRQ domain\n"); + return -ENOMEM; + } + + irq_domain_update_bus_token(msi->irq_domain, DOMAIN_BUS_NEXUS); + + msi->msi_domain = pci_msi_create_irq_domain(fwnode, + &dw_pcie_msi_domain_info, + msi->irq_domain); + if (!msi->msi_domain) { + dev_err(msi->dev, "Failed to create MSI domain\n"); + irq_domain_remove(msi->irq_domain); + return -ENOMEM; + } + + return 0; +} + +void dw_pcie_free_msi(struct dw_msi *msi) +{ + u32 ctrl; + + for (ctrl = 0; ctrl < MAX_MSI_CTRLS; ctrl++) { + if (msi->msi_irq[ctrl] > 0) + irq_set_chained_handler_and_data(msi->msi_irq[ctrl], + NULL, NULL); + } + + irq_domain_remove(msi->msi_domain); + irq_domain_remove(msi->irq_domain); +} + +void dw_pcie_msi_init(struct dw_msi *msi) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); + u32 ctrl, num_ctrls; + u64 msi_target; + + if (!pci_msi_enabled() || !msi->has_msi_ctrl) + return; + + msi_target = (u64)msi->msi_data; + num_ctrls = msi->num_vectors / MAX_MSI_IRQS_PER_CTRL; + /* Initialize IRQ Status array */ + for (ctrl = 0; ctrl < num_ctrls; ctrl++) { + dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + + (ctrl * MSI_REG_CTRL_BLOCK_SIZE), + msi->irq_mask[ctrl]); + dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_ENABLE + + (ctrl * MSI_REG_CTRL_BLOCK_SIZE), ~0); + } + + /* Program the msi_data */ + dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_LO, lower_32_bits(msi_target)); + dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_HI, upper_32_bits(msi_target)); +} + +static int dw_pcie_parse_split_msi_irq(struct dw_msi *msi, struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + u32 ctrl, max_vectors; + int irq; + + /* Parse any "msiX" IRQs described in the devicetree */ + for (ctrl = 0; ctrl < MAX_MSI_CTRLS; ctrl++) { + char msi_name[] = "msiX"; + + msi_name[3] = '0' + ctrl; + irq = platform_get_irq_byname_optional(pdev, msi_name); + if (irq == -ENXIO) + break; + if (irq < 0) + return dev_err_probe(dev, irq, + "Failed to parse MSI IRQ '%s'\n", + msi_name); + + msi->msi_irq[ctrl] = irq; + } + + /* If no "msiX" IRQs, caller should fallback to "msi" IRQ */ + if (ctrl == 0) + return -ENXIO; + + max_vectors = ctrl * MAX_MSI_IRQS_PER_CTRL; + if (msi->num_vectors > max_vectors) { + dev_warn(dev, "Exceeding number of MSI vectors, limiting to %u\n", + max_vectors); + msi->num_vectors = max_vectors; + } + if (!msi->num_vectors) + msi->num_vectors = max_vectors; + + return 0; +} + +struct dw_msi *dw_pcie_msi_host_init(struct platform_device *pdev, + void *pp, u32 num_vectors) +{ + struct device *dev = &pdev->dev; + u64 *msi_vaddr = NULL; + u32 ctrl, num_ctrls; + struct dw_msi *msi; + int ret; + + msi = devm_kzalloc(dev, sizeof(*msi), GFP_KERNEL); + if (msi == NULL) + return ERR_PTR(-ENOMEM); + + for (ctrl = 0; ctrl < MAX_MSI_CTRLS; ctrl++) + msi->irq_mask[ctrl] = ~0; + + raw_spin_lock_init(&msi->lock); + msi->dev = dev; + msi->pp = pp; + msi->has_msi_ctrl = true; + msi->num_vectors = num_vectors; + + if (!msi->msi_irq[0]) { + ret = dw_pcie_parse_split_msi_irq(msi, pdev); + if (ret < 0 && ret != -ENXIO) + return ERR_PTR(ret); + } + + if (!msi->num_vectors) + msi->num_vectors = MSI_DEF_NUM_VECTORS; + num_ctrls = msi->num_vectors / MAX_MSI_IRQS_PER_CTRL; + + if (!msi->msi_irq[0]) { + msi->msi_irq[0] = platform_get_irq_byname_optional(pdev, "msi"); + if (msi->msi_irq[0] < 0) { + msi->msi_irq[0] = platform_get_irq(pdev, 0); + if (msi->msi_irq[0] < 0) + return ERR_PTR(msi->msi_irq[0]); + } + } + + dev_dbg(dev, "Using %d MSI vectors\n", msi->num_vectors); + + msi->msi_irq_chip = &dw_pci_msi_bottom_irq_chip; + + ret = dw_pcie_allocate_domains(msi); + if (ret) + return ERR_PTR(ret); + + for (ctrl = 0; ctrl < num_ctrls; ctrl++) { + if (msi->msi_irq[ctrl] > 0) + irq_set_chained_handler_and_data(msi->msi_irq[ctrl], + dw_chained_msi_isr, msi); + } + + /* + * Even though the iMSI-RX Module supports 64-bit addresses some + * peripheral PCIe devices may lack 64-bit message support. In + * order not to miss MSI TLPs from those devices the MSI target + * address has to be within the lowest 4GB. + * + * Note until there is a better alternative found the reservation is + * done by allocating from the artificially limited DMA-coherent + * memory. + */ + ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + if (!ret) + msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &msi->msi_data, + GFP_KERNEL); + + if (!msi_vaddr) { + dev_warn(dev, "Failed to allocate 32-bit MSI address\n"); + dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); + msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &msi->msi_data, + GFP_KERNEL); + if (!msi_vaddr) { + dev_err(dev, "Failed to allocate MSI address\n"); + dw_pcie_free_msi(msi); + return ERR_PTR(-ENOMEM); + } + } + + return msi; +} diff --git a/drivers/pci/controller/dwc/pcie-designware-msi.h b/drivers/pci/controller/dwc/pcie-designware-msi.h new file mode 100644 index 0000000..633156e --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-designware-msi.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Synopsys DesignWare PCIe host controller driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * https://www.samsung.com + * + * Author: Jingoo Han + */ +#ifndef _PCIE_DESIGNWARE_MSI_H +#define _PCIE_DESIGNWARE_MSI_H + +#include "../../pci.h" + +#define MAX_MSI_IRQS 256 +#define MAX_MSI_IRQS_PER_CTRL 32 +#define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL) +#define MSI_REG_CTRL_BLOCK_SIZE 12 +#define MSI_DEF_NUM_VECTORS 32 + +struct dw_msi { + struct device *dev; + struct irq_domain *irq_domain; + struct irq_domain *msi_domain; + struct irq_chip *msi_irq_chip; + int msi_irq[MAX_MSI_CTRLS]; + dma_addr_t msi_data; + u32 num_vectors; + u32 irq_mask[MAX_MSI_CTRLS]; + raw_spinlock_t lock; + DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); + bool has_msi_ctrl; + void *private_data; + void *pp; +}; + +struct dw_msi *dw_pcie_msi_host_init(struct platform_device *pdev, + void *pp, u32 num_vectors); +int dw_pcie_allocate_domains(struct dw_msi *msi); +void dw_pcie_msi_init(struct dw_msi *msi); +void dw_pcie_free_msi(struct dw_msi *msi); +irqreturn_t dw_handle_msi_irq(struct dw_msi *msi); +#endif /* _PCIE_DESIGNWARE_MSI_H */ diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 1b5aba1..e84298e 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -22,6 +22,7 @@ #include "../../pci.h" #include "pcie-designware.h" +#include "pcie-designware-msi.h" static const char * const dw_pcie_app_clks[DW_PCIE_NUM_APP_CLKS] = { [DW_PCIE_DBI_CLK] = "dbi", diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index ef84931..8b7fddf 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -232,12 +232,6 @@ #define DEFAULT_DBI_ATU_OFFSET (0x3 << 20) #define DEFAULT_DBI_DMA_OFFSET PCIE_DMA_UNROLL_BASE -#define MAX_MSI_IRQS 256 -#define MAX_MSI_IRQS_PER_CTRL 32 -#define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL) -#define MSI_REG_CTRL_BLOCK_SIZE 12 -#define MSI_DEF_NUM_VECTORS 32 - /* Maximum number of inbound/outbound iATUs */ #define MAX_IATU_IN 256 #define MAX_IATU_OUT 256 @@ -319,7 +313,6 @@ struct dw_pcie_host_ops { }; struct dw_pcie_rp { - bool has_msi_ctrl:1; bool cfg0_io_shared:1; u64 cfg0_base; void __iomem *va_cfg0_base; @@ -329,16 +322,10 @@ struct dw_pcie_rp { u32 io_size; int irq; const struct dw_pcie_host_ops *ops; - int msi_irq[MAX_MSI_CTRLS]; - struct irq_domain *irq_domain; - struct irq_domain *msi_domain; - dma_addr_t msi_data; - struct irq_chip *msi_irq_chip; u32 num_vectors; - u32 irq_mask[MAX_MSI_CTRLS]; + struct dw_msi *msi; struct pci_host_bridge *bridge; raw_spinlock_t lock; - DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); bool use_atu_msg; int msg_atu_index; struct resource *msg_res; @@ -639,19 +626,12 @@ static inline enum dw_pcie_ltssm dw_pcie_get_ltssm(struct dw_pcie *pci) } #ifdef CONFIG_PCIE_DW_HOST -irqreturn_t dw_handle_msi_irq(struct dw_pcie_rp *pp); int dw_pcie_setup_rc(struct dw_pcie_rp *pp); int dw_pcie_host_init(struct dw_pcie_rp *pp); void dw_pcie_host_deinit(struct dw_pcie_rp *pp); -int dw_pcie_allocate_domains(struct dw_pcie_rp *pp); void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn, int where); #else -static inline irqreturn_t dw_handle_msi_irq(struct dw_pcie_rp *pp) -{ - return IRQ_NONE; -} - static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp) { return 0; @@ -666,10 +646,6 @@ static inline void dw_pcie_host_deinit(struct dw_pcie_rp *pp) { } -static inline int dw_pcie_allocate_domains(struct dw_pcie_rp *pp) -{ - return 0; -} static inline void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn, int where) diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c index d99e12f..6139330 100644 --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c @@ -16,6 +16,7 @@ #include "../../pci.h" #include "pcie-designware.h" +#include "pcie-designware-msi.h" /* Renesas-specific */ /* PCIe Mode Setting Register 0 */ diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 804341b..f415fa1 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -34,6 +34,7 @@ #include #include #include "../../pci.h" +#include "pcie-designware-msi.h" #define TEGRA194_DWC_IP_VER 0x490A #define TEGRA234_DWC_IP_VER 0x562A @@ -2407,6 +2408,7 @@ static int tegra_pcie_dw_resume_early(struct device *dev) static void tegra_pcie_dw_shutdown(struct platform_device *pdev) { struct tegra_pcie_dw *pcie = platform_get_drvdata(pdev); + struct dw_msi *msi; if (pcie->of_data->mode == DW_PCIE_RC_TYPE) { if (!pcie->link_state) @@ -2415,9 +2417,10 @@ static void tegra_pcie_dw_shutdown(struct platform_device *pdev) debugfs_remove_recursive(pcie->debugfs); tegra_pcie_downstream_dev_to_D0(pcie); + msi = pcie->pci.pp.msi; disable_irq(pcie->pci.pp.irq); if (IS_ENABLED(CONFIG_PCI_MSI)) - disable_irq(pcie->pci.pp.msi_irq[0]); + disable_irq(msi->msi_irq[0]); tegra_pcie_dw_pme_turnoff(pcie); tegra_pcie_unconfig_controller(pcie); From patchwork Mon Jul 15 18:13:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mayank Rana X-Patchwork-Id: 13733783 X-Patchwork-Delegate: manivannanece23@gmail.com Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 510F354670; Mon, 15 Jul 2024 18:14:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067295; cv=none; b=VZ2ZQ1tUSBfhD/RDg3WmZgk2wHcTNeWNR2aJMQG4CxojfvUJ0TC/PzJiEpS+8FkSX80ubMj/pWj+C4IVzlLZ/+JoEjgn9GLocYMepe+KDzXvNJ1F5Yff6BjVsurvrSL4AqT95iLJKf/x7IvOR+eYwB31P8p4nmoNPAwbajPCe/A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067295; c=relaxed/simple; bh=jAy1Gx1OwKTWMdqwcGmMUlFcOi4Kd5uKzJFshqI9F3I=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MCSLnKUmxzveeTrYzhZ2N9BBOS9Ts+wpibixd8RL+pTVV8J78P0tXW8nGTIvUjDCsh2VK1Q8jCTDM141TO2H2KSaH4wXTOhqhf7AIwurekcHER9oaduCAHmePnN4WXRfCUAEuMmaMVGzmKpfLuBLefWiR5MjLEtP/6GoY0HNRdE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=f5GKmpER; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="f5GKmpER" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46FH97g9015665; Mon, 15 Jul 2024 18:13:54 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=mrYMruISrghUxd+LH+/OO+b5 GKFMf/UAsE4wqzMTguo=; b=f5GKmpER3Hh902/gtYhxjgUDK6nWxQtFVJEOWlTO RgtzY3ovIJLb61FZY12YEiP9WauKMyDoZBANflX4ej/HC/DeyDeWtR0VC0cxAHNd iz/lUnk20Eij11rnGDOCZXt2O31DhFHE6ndEU0Mmrvgi/scHDiyUSK+RVbCAVsmW pFUG1om9jGspb169MGk0PlquiZ05PcV2xN0Z04gIM23Tp+BF/rUVOww5eXfZZxfE frOZ+ikG+jXKqZHVefjxxhxVMMEH40G1i86izQmyg3Wqo+pAYbQTB6lbvlZRdWJl 6DhTAgzb1kir/4tYp3kG+XiRuM4WZiw9bePoJox00eviAQ== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40bhnun032-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:54 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA05.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 46FIDqju001419 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:53 GMT Received: from hu-mrana-lv.qualcomm.com (10.49.16.6) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Mon, 15 Jul 2024 11:13:52 -0700 From: Mayank Rana To: , , , , , , , , , , , , , , , , , , , , , , , CC: , , , , , Mayank Rana Subject: [PATCH V2 3/7] PCI: dwc: Add pcie-designware-msi driver related Kconfig option Date: Mon, 15 Jul 2024 11:13:31 -0700 Message-ID: <1721067215-5832-4-git-send-email-quic_mrana@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> References: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nalasex01c.na.qualcomm.com (10.47.97.35) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: OQNNqHbilP3_-ic9EY_h5EF22fVMgCk2 X-Proofpoint-GUID: OQNNqHbilP3_-ic9EY_h5EF22fVMgCk2 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-15_12,2024-07-11_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 impostorscore=0 mlxscore=0 lowpriorityscore=0 mlxlogscore=999 suspectscore=0 phishscore=0 clxscore=1015 spamscore=0 malwarescore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2406140001 definitions=main-2407150142 PCIe designware MSI driver (pcie-designware-msi.c) shall be used without enabling pcie-designware core drivers (e.g. usage with ECAM driver). Hence add Kconfig option to enable pcie-designware-msi driver as separate module. Signed-off-by: Mayank Rana --- drivers/pci/controller/dwc/Kconfig | 8 ++++++++ drivers/pci/controller/dwc/Makefile | 3 ++- drivers/pci/controller/dwc/pcie-designware-msi.h | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index 8afacc9..a4c8920 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig @@ -6,8 +6,16 @@ menu "DesignWare-based PCIe controllers" config PCIE_DW bool +config PCIE_DW_MSI + bool "DWC PCIe based MSI controller" + depends on PCI_MSI + help + Say Y here to enable DWC PCIe based MSI controller to support + MSI functionality. + config PCIE_DW_HOST bool + select PCIE_DW_MSI select PCIE_DW config PCIE_DW_EP diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile index 2ecc603..9e8e4515 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PCIE_DW) += pcie-designware.o -obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o pcie-designware-msi.o +obj-$(CONFIG_PCIE_DW_MSI) += pcie-designware-msi.o +obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o diff --git a/drivers/pci/controller/dwc/pcie-designware-msi.h b/drivers/pci/controller/dwc/pcie-designware-msi.h index cf5c612..2872775f 100644 --- a/drivers/pci/controller/dwc/pcie-designware-msi.h +++ b/drivers/pci/controller/dwc/pcie-designware-msi.h @@ -40,10 +40,24 @@ struct dw_msi { void *private_data; }; +#if IS_ENABLED(CONFIG_PCIE_DW_MSI) struct dw_msi *dw_pcie_msi_host_init(struct platform_device *pdev, struct dw_msi_ops *ops, u32 num_vectors); int dw_pcie_allocate_domains(struct dw_msi *msi); void dw_pcie_msi_init(struct dw_msi *msi); void dw_pcie_free_msi(struct dw_msi *msi); irqreturn_t dw_handle_msi_irq(struct dw_msi *msi); +#else +static inline struct dw_msi *dw_pcie_msi_host_init(struct platform_device *pdev, + struct dw_msi_ops *ops, u32 num_vectors) +{ return ERR_PTR(-ENODEV); } +static inline int dw_pcie_allocate_domains(struct dw_msi *msi) +{ return -ENODEV; } +static inline void dw_pcie_msi_init(struct dw_msi *msi) +{ } +static inline void dw_pcie_free_msi(struct dw_msi *msi) +{ } +static inline irqreturn_t dw_handle_msi_irq(struct dw_msi *msi) +{ return IRQ_NONE; } +#endif #endif /* _PCIE_DESIGNWARE_MSI_H */ From patchwork Mon Jul 15 18:13:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mayank Rana X-Patchwork-Id: 13733780 X-Patchwork-Delegate: manivannanece23@gmail.com Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC36861FFA; Mon, 15 Jul 2024 18:14:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067289; cv=none; b=oTGcUVnDhedkfsmjTwRmqjVu1YR8bCqLcQNMuj43A4lDmTkgLGem4ZJjt2ay+4PY3d+AOZzrxN1LfL30gVQj+KFHRTPoZKLkS/MnSpFWM/PRZzpL59aYfdcgJATzUwNlGSYOaL8aO9Qgo2DYmyl6Ai+LW7bhdWVsx6qDznGHZ1I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067289; c=relaxed/simple; bh=ytflwCbndf2PIEdosUibN8pAfgS9K0ejUok9EPJ4FM0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=oMwWGAuqCCWXEAYxbYSwGq8GHnXTyN37Isi4pB6GPIXsfk/MuZWztU6mud+BDB5MuCfqbkumVvoXXQubaAB2Wio7vmct3riBtN/HtXjGAs4jQU3YfUZD5M1BOZu64YvWU2BMH0HmdkgNGxZfG/EHymmvemiRIwlIvQM507ybeFY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=lS6agY13; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="lS6agY13" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46FH8k9F002804; Mon, 15 Jul 2024 18:13:54 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=N7E2tf/VU0GjmPHehzNC2n8F /V5s5MVt9PCvkAORP6U=; b=lS6agY13ZMRvq9kWor5EX0geR2pfbfoXHT0jbzz3 HRPtwxmyeVPnH8tbTwmy7wHxxuGTioGEYYoLwCKcPGaG65ITXo9H+76ck0ptdngk EFvwF9fBSAwmMtATqgPPEtv5K7hN3iXYpcHg/X1Hgt8gVLuYBhSbKBzzo8bRHbDg XfvtMZbxt/GXVac5WTDXZfSmWgz9VMck6Et/9hCz9G3qp24lc+hCNXr9AwH5kfjI p8D7dCVX87+kOh5AewRkBY1nrOsUdwbzWbNiwvQqxQVDnC3OXE9D2M8I2JlNWBed yPs+QhGU2u0jltuk41995E6KjIPUPIjZg0i2erbNQFO87A== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40bhy6w173-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:54 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA05.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 46FIDqjv001419 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:53 GMT Received: from hu-mrana-lv.qualcomm.com (10.49.16.6) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Mon, 15 Jul 2024 11:13:52 -0700 From: Mayank Rana To: , , , , , , , , , , , , , , , , , , , , , , , CC: , , , , , Mayank Rana Subject: [PATCH V2 4/7] dt-bindings: PCI: host-generic-pci: Add power-domains related binding Date: Mon, 15 Jul 2024 11:13:32 -0700 Message-ID: <1721067215-5832-5-git-send-email-quic_mrana@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> References: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nalasex01c.na.qualcomm.com (10.47.97.35) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: usOy6gXqrJqfYPRU27urlHDQpNYw_qcg X-Proofpoint-ORIG-GUID: usOy6gXqrJqfYPRU27urlHDQpNYw_qcg X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-15_12,2024-07-11_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 spamscore=0 mlxscore=0 malwarescore=0 adultscore=0 suspectscore=0 phishscore=0 priorityscore=1501 bulkscore=0 mlxlogscore=999 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2406140001 definitions=main-2407150142 Add "power-domains" usage (optional) related binding to power up ECAM compliant PCIe root complex. Signed-off-by: Mayank Rana --- Documentation/devicetree/bindings/pci/host-generic-pci.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/host-generic-pci.yaml b/Documentation/devicetree/bindings/pci/host-generic-pci.yaml index 3484e0b..9c714fa 100644 --- a/Documentation/devicetree/bindings/pci/host-generic-pci.yaml +++ b/Documentation/devicetree/bindings/pci/host-generic-pci.yaml @@ -110,6 +110,12 @@ properties: iommu-map-mask: true msi-parent: true + power-domains: + maxItems: 1 + description: + A phandle to the node that controls power or/and system resource or interface to firmware + to enable ECAM compliant PCIe root complex. + required: - compatible - reg @@ -172,6 +178,7 @@ examples: // PCI_DEVICE(3) INT#(1) interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + power-domains = <&scmi5_pd 0>; }; }; ... From patchwork Mon Jul 15 18:13:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mayank Rana X-Patchwork-Id: 13733777 X-Patchwork-Delegate: manivannanece23@gmail.com Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D0C8761FFA; Mon, 15 Jul 2024 18:14:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067287; cv=none; b=KFcPtWp5C8Vm3Gdtd4MY4y/hbWD4dyMEAZDYQCuiN6MhqS5hdGffI07t68d7pa3jeKS03JuyA/zsCBR24MwDJqbeb+JXI6vXFYYxh6xpKbTsAE7UKk6G9iQwsoh+hijsSICJ8jgBoZtrnL7vA/ncl34BxPmZFrVYYgDbV6/ZsXc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067287; c=relaxed/simple; bh=iijeqEy/27APwBwGb5GwgrmSs08E04QSvdbgAaZOwuM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IotN3+iepN2J7YId7+iyd0y31OH9H/n7afVIjUELBKm6o6XUdrzcwUyg2TuSm27JYpHBjWRgR6lvqox5vih39Eh5qWuqhaxP5y+5mEMB1ilR5KetADOMov4ppVoZIHvx350/k7L2i2lPQxz72htiXwOJAg2j2N/L65EA579fHH4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=o+sBeQIC; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="o+sBeQIC" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46FH9bbJ001777; Mon, 15 Jul 2024 18:13:54 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=KtEqsKKyAId6WCwFuWmtXjap IMQ6lcIUriKWZ69bLDE=; b=o+sBeQIC9Q9MVh08iqfelLQ2IX9jZ08inM7sRNCl n5yj/cKsFuRPX16g6aSdPy082T1OMFdVSH92uxe41NGTqyr5SFFO1u0mMWtqP0rh 6y9/ylXRHJnCHtGJDo1mNVFDZvG5X/Gnx52jjGpGFOiyjcrU4zxUb1tOD3XqUnvm 2V2AqENaW5W7s+pLGPuyoGRb2XanJ6t+A9RdirZKRj9muWqUwlE/7VoD4Zw27c1D +Ae7c4lS0MeLGmE/lq7VuB5OCFUGcU1DcMxI5WRqlBCJ2ZnPaRKsxg2qeEa8VHUR 5aJ4GsrB48wlLGB0CDtVbAPjYTnQa1xlYbeM4IHNMiVXeg== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40bjbh4up8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:54 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA03.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 46FIDrKj011266 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:53 GMT Received: from hu-mrana-lv.qualcomm.com (10.49.16.6) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Mon, 15 Jul 2024 11:13:53 -0700 From: Mayank Rana To: , , , , , , , , , , , , , , , , , , , , , , , CC: , , , , , Mayank Rana Subject: [PATCH V2 5/7] PCI: host-generic: Add power domain based handling for PCIe controller Date: Mon, 15 Jul 2024 11:13:33 -0700 Message-ID: <1721067215-5832-6-git-send-email-quic_mrana@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> References: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nalasex01c.na.qualcomm.com (10.47.97.35) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: JMtVsoSUwacfvcTCm72XoCPtsZeg-yZk X-Proofpoint-GUID: JMtVsoSUwacfvcTCm72XoCPtsZeg-yZk X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-15_12,2024-07-11_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 adultscore=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 priorityscore=1501 clxscore=1015 spamscore=0 mlxlogscore=999 mlxscore=0 phishscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2406140001 definitions=main-2407150142 Add usage of power domain to control PCIe controller enumeration. This is needed to allow interaction with firmware to vote/unvote system resources, PCIe PHY and configuration of PCIe controller into ECAM mode. This feature support system suspend and resume to put PCIe into D3 cold and D0. Signed-off-by: Mayank Rana --- drivers/pci/controller/pci-host-generic.c | 42 +++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/pci-host-generic.c b/drivers/pci/controller/pci-host-generic.c index 41cb6a0..c2c027f 100644 --- a/drivers/pci/controller/pci-host-generic.c +++ b/drivers/pci/controller/pci-host-generic.c @@ -13,6 +13,7 @@ #include #include #include +#include static const struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = { .bus_shift = 16, @@ -76,13 +77,50 @@ static const struct of_device_id gen_pci_of_match[] = { }; MODULE_DEVICE_TABLE(of, gen_pci_of_match); +static int gen_pcie_ecam_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret = 0; + + if (!IS_ERR_OR_NULL(dev->pm_domain)) { + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; + + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) { + dev_err(dev, "fail to enable pcie controller:%d\n", ret); + return ret; + } + } + + ret = pci_host_common_probe(pdev); + if (ret) { + dev_err(dev, "pci_host_common_probe() failed:%d\n", ret); + goto err; + } + + return ret; +err: + if (!IS_ERR_OR_NULL(dev->pm_domain)) + pm_runtime_put_sync(dev); + return ret; +} + +static void gen_pcie_ecam_remove(struct platform_device *pdev) +{ + pci_host_common_remove(pdev); + if (pdev->dev.pm_domain) + pm_runtime_put_sync(&pdev->dev); +} + static struct platform_driver gen_pci_driver = { .driver = { .name = "pci-host-generic", .of_match_table = gen_pci_of_match, }, - .probe = pci_host_common_probe, - .remove_new = pci_host_common_remove, + .probe = gen_pcie_ecam_probe, + .remove_new = gen_pcie_ecam_remove, }; module_platform_driver(gen_pci_driver); From patchwork Mon Jul 15 18:13:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mayank Rana X-Patchwork-Id: 13733782 X-Patchwork-Delegate: manivannanece23@gmail.com Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C62426E61B; Mon, 15 Jul 2024 18:14:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067295; cv=none; b=hsGGJO7/mX90HKX/pPBF3r0gvJwB1FEb+nwg5eOFub2ROyDWp9wJGIaBGlCsltSE8EyoIo1d7q9GsWLQv6E86O0lN1rcYcsJsKrbDRuKpjeGZBjqMg97lvXDCSXqjtYaD1VSOY3KptsFPXsbESorbjdm28IClR0yb8r0iXbR2iw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067295; c=relaxed/simple; bh=GsFSFiK+aj+yQoi1frw7uVd0xhFPQHzitvU8lWv5Vx8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pGbUB1zgPAUpoTATr3y2/8t0QQAVWxmqb59KhtK7TCaWqxjvC4eYlpM2cmmqKWz7TSCMhmKyemRJ/45o/XjSqwRjoE5qlFuozMqgHPyfGK1+nZQRhw4mLAzxPWQJeoALG1gl4SzbCa2ilOH8wHhHNNUPfD1JxXh+lw09Pxl8+8g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=Q60kSvph; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="Q60kSvph" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46FH8gjl029987; Mon, 15 Jul 2024 18:13:55 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=c7owLXpFna1dFjNdHfNbwtJ+ e/sHELDIGCOsgbwDi7k=; b=Q60kSvphq2xIVOGd4LV5oa54fKfTyzVPQZTUg6UU SDAdRUVEtPV+T8GKsA9WF36A07JAtNX1ETPFg6hg7yy8b1553waS+yPYhNnhvGNp gnymCGcyeXESc8S7MRYWIhUlahyh2QA/mv+tflu76YiRgrhJ4IYXpeyEqu+ZXNEo /0NLvTuPgW5me+RwLwicqiaj6NAvB4HI/IrPWvO+/OmKD/YIov5AcXzJHdMuxidX i0chdbyg6s4Xcr+/cUpJmMP8HnHaWU4zE41aOssiFDK7hoWw7KRhcuIVR+SsHtiA VG9bsYqQ1wEDoZcAcayRQ7R7Hj65y6bbDOgeFuZOLoIZbw== Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40bf9ed68k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:55 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA04.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 46FIDsbr003669 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:54 GMT Received: from hu-mrana-lv.qualcomm.com (10.49.16.6) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Mon, 15 Jul 2024 11:13:53 -0700 From: Mayank Rana To: , , , , , , , , , , , , , , , , , , , , , , , CC: , , , , , Mayank Rana Subject: [PATCH V2 7/7] PCI: host-generic: Add dwc PCIe controller based MSI controller usage Date: Mon, 15 Jul 2024 11:13:35 -0700 Message-ID: <1721067215-5832-8-git-send-email-quic_mrana@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> References: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nalasex01c.na.qualcomm.com (10.47.97.35) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: GHBMqoNpPxgEnql2LIncftsiqsmH4MN- X-Proofpoint-GUID: GHBMqoNpPxgEnql2LIncftsiqsmH4MN- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-15_12,2024-07-11_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 priorityscore=1501 bulkscore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 spamscore=0 phishscore=0 mlxlogscore=999 mlxscore=0 adultscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2406140001 definitions=main-2407150142 Add usage of Synopsys Designware PCIe controller based MSI controller to support MSI functionality with ECAM compliant Synopsys Designware PCIe controller. To use this functionality add device compatible string as "snps,dw-pcie-ecam-msi". Signed-off-by: Mayank Rana --- drivers/pci/controller/pci-host-generic.c | 92 ++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/pci-host-generic.c b/drivers/pci/controller/pci-host-generic.c index c2c027f..457ae44 100644 --- a/drivers/pci/controller/pci-host-generic.c +++ b/drivers/pci/controller/pci-host-generic.c @@ -8,13 +8,73 @@ * Author: Will Deacon */ -#include #include +#include #include +#include #include #include #include +#include "dwc/pcie-designware-msi.h" + +struct dw_ecam_pcie { + void __iomem *cfg; + struct dw_msi *msi; + struct pci_host_bridge *bridge; +}; + +static u32 dw_ecam_pcie_readl(void *p_data, u32 reg) +{ + struct dw_ecam_pcie *ecam_pcie = (struct dw_ecam_pcie *)p_data; + + return readl(ecam_pcie->cfg + reg); +} + +static void dw_ecam_pcie_writel(void *p_data, u32 reg, u32 val) +{ + struct dw_ecam_pcie *ecam_pcie = (struct dw_ecam_pcie *)p_data; + + writel(val, ecam_pcie->cfg + reg); +} + +static struct dw_ecam_pcie *dw_pcie_ecam_msi(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct dw_ecam_pcie *ecam_pcie; + struct dw_msi_ops *msi_ops; + u64 addr; + + ecam_pcie = devm_kzalloc(dev, sizeof(*ecam_pcie), GFP_KERNEL); + if (!ecam_pcie) + return ERR_PTR(-ENOMEM); + + if (of_property_read_reg(dev->of_node, 0, &addr, NULL) < 0) { + dev_err(dev, "Failed to get reg address\n"); + return ERR_PTR(-ENODEV); + } + + ecam_pcie->cfg = devm_ioremap(dev, addr, PAGE_SIZE); + if (ecam_pcie->cfg == NULL) + return ERR_PTR(-ENOMEM); + + msi_ops = devm_kzalloc(dev, sizeof(*msi_ops), GFP_KERNEL); + if (!msi_ops) + return ERR_PTR(-ENOMEM); + + msi_ops->readl_msi = dw_ecam_pcie_readl; + msi_ops->writel_msi = dw_ecam_pcie_writel; + msi_ops->pp = ecam_pcie; + ecam_pcie->msi = dw_pcie_msi_host_init(pdev, msi_ops, 0); + if (IS_ERR(ecam_pcie->msi)) { + dev_err(dev, "dw_pcie_msi_host_init() failed\n"); + return ERR_PTR(-EINVAL); + } + + dw_pcie_msi_init(ecam_pcie->msi); + return ecam_pcie; +} + static const struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = { .bus_shift = 16, .pci_ops = { @@ -73,6 +133,9 @@ static const struct of_device_id gen_pci_of_match[] = { { .compatible = "snps,dw-pcie-ecam", .data = &pci_dw_ecam_bus_ops }, + { .compatible = "snps,dw-pcie-ecam-msi", + .data = &pci_generic_ecam_ops }, + { }, }; MODULE_DEVICE_TABLE(of, gen_pci_of_match); @@ -80,6 +143,7 @@ MODULE_DEVICE_TABLE(of, gen_pci_of_match); static int gen_pcie_ecam_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct dw_ecam_pcie *ecam_pcie = NULL; int ret = 0; if (!IS_ERR_OR_NULL(dev->pm_domain)) { @@ -94,14 +158,30 @@ static int gen_pcie_ecam_probe(struct platform_device *pdev) } } + if (of_device_is_compatible(dev->of_node, "snps,dw-pcie-ecam-msi")) { + ecam_pcie = dw_pcie_ecam_msi(pdev); + if (IS_ERR(ecam_pcie)) { + ret = -ENODEV; + goto err; + } + } + ret = pci_host_common_probe(pdev); if (ret) { dev_err(dev, "pci_host_common_probe() failed:%d\n", ret); goto err; } + if (ecam_pcie) { + ecam_pcie->bridge = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, ecam_pcie); + } + return ret; err: + if (!IS_ERR_OR_NULL(ecam_pcie)) + dw_pcie_free_msi(ecam_pcie->msi); + if (!IS_ERR_OR_NULL(dev->pm_domain)) pm_runtime_put_sync(dev); return ret; @@ -109,7 +189,17 @@ static int gen_pcie_ecam_probe(struct platform_device *pdev) static void gen_pcie_ecam_remove(struct platform_device *pdev) { + struct dw_ecam_pcie *ecam_pcie = NULL; + + if (of_device_is_compatible(pdev->dev.of_node, "snps,dw-pcie-ecam-msi")) { + ecam_pcie = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, ecam_pcie->bridge); + } + pci_host_common_remove(pdev); + if (ecam_pcie) + dw_pcie_free_msi(ecam_pcie->msi); + if (pdev->dev.pm_domain) pm_runtime_put_sync(&pdev->dev); } From patchwork Mon Jul 15 18:13:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mayank Rana X-Patchwork-Id: 13733781 X-Patchwork-Delegate: manivannanece23@gmail.com Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D75C77102; Mon, 15 Jul 2024 18:14:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067289; cv=none; b=P4S8ksFvhjHVTMlBlsCTbUM+xjWPPUXuTM7l+Cm53teviqkKWQTaVSygfgoVEbzi90jHTmcWo6v/nvPxaeJQFjebeidYt+XlcwFqi792CblxJZw0xRaUIevixDlRZKyoaXDQ6ngh13z6qErAqMoh7QyUIYLKQETuzB77CAiYO1I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067289; c=relaxed/simple; bh=+poeAqJsZY9LbSVXnYITZWtVjYjabmv+yobXW+UrZGY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=aFJ/aFM2hy8IbirLXsou50jN40vrt7WYE0PKXqQCpAV7ur1+PpMX3qCj7sd275PEC+kPgMla47gTSu2T4FGzLkHTBzPx7XbdPAMrR+lKzo01eNHt71cFSlwcuRO9Of04PBCkC8TTGAWl3Ml2PB8pJrXbMzOPpeFpXKKVjo0z2II= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=U7ZzDLCm; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="U7ZzDLCm" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46FH8h0o002695; Mon, 15 Jul 2024 18:13:54 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=dB1MeVxgK7PLtAVG7XzzE3SB RfycrqHx2a72LtOGaCw=; b=U7ZzDLCmlBWqtoTCsAdLwY7WiK8VYzqlSlQlcqRh KX6FXwlyTMrJxBiH7fM8iOlRcp1KaPSrRAaZ5WmUp5GF2jhPc02EKriTq2vbCLYt ikCX/5Tx62GaEeVivHkSrKXb++w0hXY5uLOeXOTBo5xlkKz8pZGhHs6ldWtgVmwI jym85qWdia7CwZdiuDtNo1e6gtQSC4DH9lOaV93nqYz734km80HNVuqzYrydG72P PogkUVzSmMzVzKt0SpbR337IZecBbAbyEf8a83RR/cTaThjjACWwHNnkihCcto5O nIuHTtFTgyuvx9pBn2tQgsVvZWtAQ0ioJtzWxW6zR5LEhg== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40bhy6w172-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:54 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA02.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 46FIDq4u027898 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:52 GMT Received: from hu-mrana-lv.qualcomm.com (10.49.16.6) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Mon, 15 Jul 2024 11:13:52 -0700 From: Mayank Rana To: , , , , , , , , , , , , , , , , , , , , , , , CC: , , , , , Mayank Rana Subject: [PATCH V222/7] PCI: dwc: Add msi_ops to allow DBI based MSI register access Date: Mon, 15 Jul 2024 11:13:30 -0700 Message-ID: <1721067215-5832-3-git-send-email-quic_mrana@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> References: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nalasex01c.na.qualcomm.com (10.47.97.35) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: QXnSMJVv9URGOAupC_PenYEsxYQr4cAB X-Proofpoint-ORIG-GUID: QXnSMJVv9URGOAupC_PenYEsxYQr4cAB X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-15_12,2024-07-11_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 spamscore=0 mlxscore=0 malwarescore=0 adultscore=0 suspectscore=0 phishscore=0 priorityscore=1501 bulkscore=0 mlxlogscore=999 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2406140001 definitions=main-2407150142 PCIe ECAM driver do not have dw_pcie data structure populated and DBI access related APIs. Hence add msi_ops as part of dw_msi structure to allow populating DBI based MSI register access. Signed-off-by: Mayank Rana --- drivers/pci/controller/dwc/pcie-designware-host.c | 20 ++++++++++++- drivers/pci/controller/dwc/pcie-designware-msi.c | 36 +++++++++++++---------- drivers/pci/controller/dwc/pcie-designware-msi.h | 10 +++++-- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 3dcf88a..7a1eb1f 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -47,6 +47,16 @@ static void dw_pcie_host_request_msg_tlp_res(struct dw_pcie_rp *pp) } } +static u32 dw_pcie_readl_msi_dbi(void *pci, u32 reg) +{ + return dw_pcie_readl_dbi((struct dw_pcie *)pci, reg); +} + +static void dw_pcie_writel_msi_dbi(void *pci, u32 reg, u32 val) +{ + dw_pcie_writel_dbi((struct dw_pcie *)pci, reg, val); +} + int dw_pcie_host_init(struct dw_pcie_rp *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -55,6 +65,7 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) struct platform_device *pdev = to_platform_device(dev); struct resource_entry *win; struct pci_host_bridge *bridge; + struct dw_msi_ops *msi_ops; struct resource *res; bool has_msi_ctrl; int ret; @@ -124,7 +135,14 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) if (ret < 0) goto err_deinit_host; } else if (has_msi_ctrl) { - pp->msi = dw_pcie_msi_host_init(pdev, pp, pp->num_vectors); + msi_ops = devm_kzalloc(dev, sizeof(*msi_ops), GFP_KERNEL); + if (msi_ops == NULL) + goto err_deinit_host; + + msi_ops->pp = pci; + msi_ops->readl_msi = dw_pcie_readl_msi_dbi, + msi_ops->writel_msi = dw_pcie_writel_msi_dbi, + pp->msi = dw_pcie_msi_host_init(pdev, msi_ops, pp->num_vectors); if (IS_ERR(pp->msi)) { ret = PTR_ERR(pp->msi); goto err_deinit_host; diff --git a/drivers/pci/controller/dwc/pcie-designware-msi.c b/drivers/pci/controller/dwc/pcie-designware-msi.c index 39fe5be..dbfffce 100644 --- a/drivers/pci/controller/dwc/pcie-designware-msi.c +++ b/drivers/pci/controller/dwc/pcie-designware-msi.c @@ -44,6 +44,16 @@ static struct msi_domain_info dw_pcie_msi_domain_info = { .chip = &dw_pcie_msi_irq_chip, }; +static u32 dw_msi_readl(struct dw_msi *msi, u32 reg) +{ + return msi->msi_ops->readl_msi(msi->msi_ops->pp, reg); +} + +static void dw_msi_writel(struct dw_msi *msi, u32 reg, u32 val) +{ + msi->msi_ops->writel_msi(msi->msi_ops->pp, reg, val); +} + /* MSI int handler */ irqreturn_t dw_handle_msi_irq(struct dw_msi *msi) { @@ -51,13 +61,11 @@ irqreturn_t dw_handle_msi_irq(struct dw_msi *msi) unsigned long val; u32 status, num_ctrls; irqreturn_t ret = IRQ_NONE; - struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); num_ctrls = msi->num_vectors / MAX_MSI_IRQS_PER_CTRL; for (i = 0; i < num_ctrls; i++) { - status = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS + - (i * MSI_REG_CTRL_BLOCK_SIZE)); + status = dw_msi_readl(msi, PCIE_MSI_INTR0_STATUS + (i * MSI_REG_CTRL_BLOCK_SIZE)); if (!status) continue; @@ -115,7 +123,6 @@ static int dw_pci_msi_set_affinity(struct irq_data *d, static void dw_pci_bottom_mask(struct irq_data *d) { struct dw_msi *msi = irq_data_get_irq_chip_data(d); - struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); unsigned int res, bit, ctrl; unsigned long flags; @@ -126,7 +133,7 @@ static void dw_pci_bottom_mask(struct irq_data *d) bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; msi->irq_mask[ctrl] |= BIT(bit); - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, msi->irq_mask[ctrl]); + dw_msi_writel(msi, PCIE_MSI_INTR0_MASK + res, msi->irq_mask[ctrl]); raw_spin_unlock_irqrestore(&msi->lock, flags); } @@ -134,7 +141,6 @@ static void dw_pci_bottom_mask(struct irq_data *d) static void dw_pci_bottom_unmask(struct irq_data *d) { struct dw_msi *msi = irq_data_get_irq_chip_data(d); - struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); unsigned int res, bit, ctrl; unsigned long flags; @@ -145,7 +151,7 @@ static void dw_pci_bottom_unmask(struct irq_data *d) bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; msi->irq_mask[ctrl] &= ~BIT(bit); - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, msi->irq_mask[ctrl]); + dw_msi_writel(msi, PCIE_MSI_INTR0_MASK + res, msi->irq_mask[ctrl]); raw_spin_unlock_irqrestore(&msi->lock, flags); } @@ -153,14 +159,13 @@ static void dw_pci_bottom_unmask(struct irq_data *d) static void dw_pci_bottom_ack(struct irq_data *d) { struct dw_msi *msi = irq_data_get_irq_chip_data(d); - struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); unsigned int res, bit, ctrl; ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_STATUS + res, BIT(bit)); + dw_msi_writel(msi, PCIE_MSI_INTR0_STATUS + res, BIT(bit)); } static struct irq_chip dw_pci_msi_bottom_irq_chip = { @@ -262,7 +267,6 @@ void dw_pcie_free_msi(struct dw_msi *msi) void dw_pcie_msi_init(struct dw_msi *msi) { - struct dw_pcie *pci = to_dw_pcie_from_pp(msi->pp); u32 ctrl, num_ctrls; u64 msi_target; @@ -273,16 +277,16 @@ void dw_pcie_msi_init(struct dw_msi *msi) num_ctrls = msi->num_vectors / MAX_MSI_IRQS_PER_CTRL; /* Initialize IRQ Status array */ for (ctrl = 0; ctrl < num_ctrls; ctrl++) { - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + + dw_msi_writel(msi, PCIE_MSI_INTR0_MASK + (ctrl * MSI_REG_CTRL_BLOCK_SIZE), msi->irq_mask[ctrl]); - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_ENABLE + + dw_msi_writel(msi, PCIE_MSI_INTR0_ENABLE + (ctrl * MSI_REG_CTRL_BLOCK_SIZE), ~0); } /* Program the msi_data */ - dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_LO, lower_32_bits(msi_target)); - dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_HI, upper_32_bits(msi_target)); + dw_msi_writel(msi, PCIE_MSI_ADDR_LO, lower_32_bits(msi_target)); + dw_msi_writel(msi, PCIE_MSI_ADDR_HI, upper_32_bits(msi_target)); } static int dw_pcie_parse_split_msi_irq(struct dw_msi *msi, struct platform_device *pdev) @@ -324,7 +328,7 @@ static int dw_pcie_parse_split_msi_irq(struct dw_msi *msi, struct platform_devic } struct dw_msi *dw_pcie_msi_host_init(struct platform_device *pdev, - void *pp, u32 num_vectors) + struct dw_msi_ops *ops, u32 num_vectors) { struct device *dev = &pdev->dev; u64 *msi_vaddr = NULL; @@ -341,7 +345,7 @@ struct dw_msi *dw_pcie_msi_host_init(struct platform_device *pdev, raw_spin_lock_init(&msi->lock); msi->dev = dev; - msi->pp = pp; + msi->msi_ops = ops; msi->has_msi_ctrl = true; msi->num_vectors = num_vectors; diff --git a/drivers/pci/controller/dwc/pcie-designware-msi.h b/drivers/pci/controller/dwc/pcie-designware-msi.h index 633156e..cf5c612 100644 --- a/drivers/pci/controller/dwc/pcie-designware-msi.h +++ b/drivers/pci/controller/dwc/pcie-designware-msi.h @@ -18,8 +18,15 @@ #define MSI_REG_CTRL_BLOCK_SIZE 12 #define MSI_DEF_NUM_VECTORS 32 +struct dw_msi_ops { + void *pp; + u32 (*readl_msi)(void *pp, u32 reg); + void (*writel_msi)(void *pp, u32 reg, u32 val); +}; + struct dw_msi { struct device *dev; + struct dw_msi_ops *msi_ops; struct irq_domain *irq_domain; struct irq_domain *msi_domain; struct irq_chip *msi_irq_chip; @@ -31,11 +38,10 @@ struct dw_msi { DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); bool has_msi_ctrl; void *private_data; - void *pp; }; struct dw_msi *dw_pcie_msi_host_init(struct platform_device *pdev, - void *pp, u32 num_vectors); + struct dw_msi_ops *ops, u32 num_vectors); int dw_pcie_allocate_domains(struct dw_msi *msi); void dw_pcie_msi_init(struct dw_msi *msi); void dw_pcie_free_msi(struct dw_msi *msi); From patchwork Mon Jul 15 18:13:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mayank Rana X-Patchwork-Id: 13733778 X-Patchwork-Delegate: manivannanece23@gmail.com Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 88A447173C; Mon, 15 Jul 2024 18:14:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067287; cv=none; b=q8NnOaTbMpfXYZzGFpJu7Zd1w+RePm0W4DEFSCcQxOu1YjlqefVFpLYNzHOBqqiq/HtU5GtbgjOZRrkEQYJL+Tippf2qcotGrb1CgITfEI1YFr8Bcf4yyoSFI7gsvrB7JdGJzrTsO5BvhJzhiRlB1Up69/qOLdMZJM1JCiuYq4s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721067287; c=relaxed/simple; bh=TgQWTBOU9Yc9+BVEnI59quvOHALQzRUmRj+EwKqFtEY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nEiMKjBHmGR0ZPbTTKv278n6z46JH4teqPMvOHTJMpYUB+Jvotu/5jMr7HT3v4RzSwpTOeZLgJgP6MvNICK0hR9fuZmIh8YSq5vBrGruIEgesjXSX/q8iS0j5R0nwHZhmJiN6x78tsyAuGDe+XGyDn1ApCwCcL7NJzduwWkBSrc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=KjHZvGGD; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="KjHZvGGD" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46FH8hPj029998; Mon, 15 Jul 2024 18:13:55 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=BsqkTxTegj2hlVRLZ9DlL6Cl I6gvd2pgo9wFqQqHL+A=; b=KjHZvGGDj4A9LDX0pzCGxxMDUxM98Yz36S8vJLqv 3asQWhiO59ExJ43nW9qIwNn60tqhK8Rh5BXG3nkpsNvPD3dkZmybpVTRRfirEXUX 3o4IJNfLM50H5OC1+2UTGM7DJH8CaP+z/iBHhfvpyxMuVuulHAXhEa1cRIg6HPje moeMDz7VOqNl72tVfjrqTJLMiPHksMOrBxIaCCFWxpQK0B5c9r1lQ3PwSryLKjuh aGBgmF69cNyIyVkG/77wz/7s/OQPGzeWjMunRYR9wF0RKV6pvgrF4j3cayuTooT1 meT0b1Ptuj6sz7YcWj+S5XexsCUQw0CIuDFKJct42wVddw== Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40bf9ed68h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:54 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA01.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 46FIDr2E026349 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 15 Jul 2024 18:13:53 GMT Received: from hu-mrana-lv.qualcomm.com (10.49.16.6) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Mon, 15 Jul 2024 11:13:53 -0700 From: Mayank Rana To: , , , , , , , , , , , , , , , , , , , , , , , CC: , , , , , Mayank Rana Subject: [PATCH V226/7] dt-bindings: PCI: host-generic-pci: Add snps,dw-pcie-ecam-msi binding Date: Mon, 15 Jul 2024 11:13:34 -0700 Message-ID: <1721067215-5832-7-git-send-email-quic_mrana@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> References: <1721067215-5832-1-git-send-email-quic_mrana@quicinc.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nalasex01c.na.qualcomm.com (10.47.97.35) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: T4gnOBKDQXQBRBiziBzzidh6lptryqV2 X-Proofpoint-GUID: T4gnOBKDQXQBRBiziBzzidh6lptryqV2 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-15_12,2024-07-11_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 priorityscore=1501 bulkscore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 spamscore=0 phishscore=0 mlxlogscore=972 mlxscore=0 adultscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2406140001 definitions=main-2407150142 To support MSI functionality using Synopsys DesignWare PCIe controller based MSI controller with ECAM driver, add "snps,dw-pcie-ecam-msi compatible binding which uses provided SPIs to support MSI functionality. Signed-off-by: Mayank Rana --- .../devicetree/bindings/pci/host-generic-pci.yaml | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/host-generic-pci.yaml b/Documentation/devicetree/bindings/pci/host-generic-pci.yaml index 9c714fa..9e860d5 100644 --- a/Documentation/devicetree/bindings/pci/host-generic-pci.yaml +++ b/Documentation/devicetree/bindings/pci/host-generic-pci.yaml @@ -81,6 +81,12 @@ properties: - marvell,armada8k-pcie-ecam - socionext,synquacer-pcie-ecam - const: snps,dw-pcie-ecam + - description: | + Firmware is configuring Synopsys DesignWare PCIe controller in RC mode with + ECAM compatible fashion. To use MSI controller of Synopsys DesignWare PCIe + controller for MSI functionality, this compatible is used. + items: + - const: snps,dw-pcie-ecam-msi - description: CAM or ECAM compliant PCI host controllers without any quirks enum: @@ -116,6 +122,20 @@ properties: A phandle to the node that controls power or/and system resource or interface to firmware to enable ECAM compliant PCIe root complex. + interrupts: + description: + DWC PCIe Root Port/Complex specific MSI interrupt/IRQs. + minItems: 1 + maxItems: 8 + + interrupt-names: + description: + MSI interrupt names + minItems: 1 + maxItems: 8 + items: + pattern: '^msi[0-9]+$' + required: - compatible - reg @@ -146,11 +166,22 @@ allOf: reg: maxItems: 1 + - if: + properties: + compatible: + contains: + const: snps,dw-pcie-ecam-msi + then: + required: + - interrupts + - interrupt-names + unevaluatedProperties: false examples: - | + #include bus { #address-cells = <2>; #size-cells = <2>; @@ -180,5 +211,31 @@ examples: interrupt-map-mask = <0xf800 0x0 0x0 0x7>; power-domains = <&scmi5_pd 0>; }; + + pcie0: pci@1c00000 { + compatible = "snps,dw-pcie-ecam-msi"; + reg = <0x4 0x00000000 0 0x10000000>; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x02000000 0x0 0x40100000 0x0 0x40100000 0x0 0x1ff00000>, + <0x43000000 0x4 0x10100000 0x4 0x10100000 0x0 0x40000000>; + bus-range = <0x00 0xff>; + dma-coherent; + linux,pci-domain = <0>; + power-domains = <&scmi5_pd 0>; + iommu-map = <0x0 &pcie_smmu 0x0000 0x1>, + <0x100 &pcie_smmu 0x0001 0x1>; + + interrupts = , + , + , + , + , + , + , + ; + interrupt-names = "msi0", "msi1", "msi2", "msi3", "msi4", "msi5", "msi6", "msi7"; + }; }; ...