Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp2469711ybh; Fri, 24 Jul 2020 13:46:34 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwSotJTv+YRGEscBvYJNsrEV6MJEY5XE3Dez8HG3gHEA1WTyYWLDuUuA8dttEINqRTwQPBq X-Received: by 2002:a17:906:7d9:: with SMTP id m25mr6844112ejc.25.1595623594335; Fri, 24 Jul 2020 13:46:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595623594; cv=none; d=google.com; s=arc-20160816; b=G6ZYJss3Y9/GYj2GHgZ/fTjr7ZSt9JhDduEXK/uBcQUh7LjGxsAeaKDvBBW+rwXBOb 2cHWydMrzSb324cMikreV3krk4kSmm/Au6YXHm5Lif0sPe+veGWuTssuFoHa6BTFi/Sh UMWQF71HKowrorAXOBhGXBf1NIyJ9ZaN4dnN+fagZEkg0JWS8MGiDxQ1W6O7MVKfYmUd WXZ28ZvrL2UpbdV45HLsAwltBrZvi8r4KHP1CP6AJYqVNkQ4FA2kTVjQ2juL9/OQ5uiQ Qy45QxSDyx4KkyKgpuOv1G+bdvCVTeEE3d80KP35FLPgtWYoBHXDBe00dLgMjJM+neLn eSzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:dkim-filter; bh=55PzWfEWug3h+L/Mz7pqSYR2oftH3xs6xKp2jSHwZug=; b=EhIZzmU6IygLFLY0TDVxidAxNO1ibvGrMyQGW7uFUAzbwa6H8QwKT9KyNUpAUtsgqF +bhmZKyY3SfnmCEEBuxWXiXaKU35hDfebAGBw41Kq1aw2/2zgZINBDEMi8SORDfSki+0 wJtuo2lnmw3bt6SN2VZVqBnVxfgZqVL73OMVUGE6oEP/2HHXRxcoKcPNfpe88nWv+Rwj rqq/pgwCAOzk7NJLGK1Kk1rT8Tba7hrA+44YFLz1/CCIe/Obm38wa1ARNAf7Joc9mjfB KPnH+1EwY32IsN3cK4CL4NBWcvAY9PUwiRQyidgivGavEk/Xb9pVjWG02nHaNhHy9DoD A6nQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@broadcom.com header.s=dkimrelay header.b=Mo4xF1EZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u8si1414192ejx.92.2020.07.24.13.46.12; Fri, 24 Jul 2020 13:46:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@broadcom.com header.s=dkimrelay header.b=Mo4xF1EZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727014AbgGXUpx (ORCPT + 99 others); Fri, 24 Jul 2020 16:45:53 -0400 Received: from rnd-relay.smtp.broadcom.com ([192.19.232.150]:34410 "EHLO rnd-relay.smtp.broadcom.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726862AbgGXUpn (ORCPT ); Fri, 24 Jul 2020 16:45:43 -0400 Received: from mail-irv-17.broadcom.com (mail-irv-17.lvn.broadcom.net [10.75.242.48]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id ED9A21A048B; Fri, 24 Jul 2020 13:36:35 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com ED9A21A048B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1595622996; bh=fEBpcSW3aFnVQwhDxRy88kreQF55GQrU9f70Lgap8NU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Mo4xF1EZ7Q7KsjKbWJGVNzRFnwPaAlOSdH8S6/aGBRho6SAm3qWcOqcsxUqrxjAqP bCjz27Xs4el+HFZhqTYiluLZ8oAluwXGdEjCLXpgXjGXWzEZ+Nzvz8ww9IFIHhCXkd IMEehbYaXmkKiJpjrAJ8wctS6tFs28H4hahd2nuM= Received: from stbsrv-and-01.and.broadcom.net (stbsrv-and-01.and.broadcom.net [10.28.16.211]) by mail-irv-17.broadcom.com (Postfix) with ESMTP id 153DC14024F; Fri, 24 Jul 2020 13:34:44 -0700 (PDT) From: Jim Quinlan To: linux-pci@vger.kernel.org, Nicolas Saenz Julienne , Christoph Hellwig , Robin Murphy , bcm-kernel-feedback-list@broadcom.com, james.quinlan@broadcom.com Cc: Jim Quinlan , Lorenzo Pieralisi , Rob Herring , Bjorn Helgaas , Florian Fainelli , linux-rpi-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v9 10/12] PCI: brcmstb: Accommodate MSI for older chips Date: Fri, 24 Jul 2020 16:33:52 -0400 Message-Id: <20200724203407.16972-11-james.quinlan@broadcom.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200724203407.16972-1-james.quinlan@broadcom.com> References: <20200724203407.16972-1-james.quinlan@broadcom.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jim Quinlan Older BrcmSTB chips do not have a separate register for MSI interrupts; the MSIs are in a register that also contains unrelated interrupts. In addition, the interrupts lie in bits [31..24] for these legacy chips. This commit provides common code for both legacy and non-legacy MSI interrupt registers. Signed-off-by: Jim Quinlan Acked-by: Florian Fainelli --- drivers/pci/controller/pcie-brcmstb.c | 71 +++++++++++++++++++-------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 3ef2d37cc43b..a2e02b2fbd36 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -82,7 +82,8 @@ #define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048 #define PCIE_MISC_MSI_DATA_CONFIG 0x404c -#define PCIE_MISC_MSI_DATA_CONFIG_VAL 0xffe06540 +#define PCIE_MISC_MSI_DATA_CONFIG_VAL_32 0xffe06540 +#define PCIE_MISC_MSI_DATA_CONFIG_VAL_8 0xfff86540 #define PCIE_MISC_PCIE_CTRL 0x4064 #define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1 @@ -94,6 +95,9 @@ #define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK 0x10 #define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK 0x40 +#define PCIE_MISC_REVISION 0x406c +#define BRCM_PCIE_HW_REV_33 0x0303 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0 @@ -114,10 +118,14 @@ #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2 #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 -#define PCIE_MSI_INTR2_STATUS 0x4500 -#define PCIE_MSI_INTR2_CLR 0x4508 -#define PCIE_MSI_INTR2_MASK_SET 0x4510 -#define PCIE_MSI_INTR2_MASK_CLR 0x4514 + +#define PCIE_INTR2_CPU_BASE 0x4300 +#define PCIE_MSI_INTR2_BASE 0x4500 +/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */ +#define MSI_INT_STATUS 0x0 +#define MSI_INT_CLR 0x8 +#define MSI_INT_MASK_SET 0x10 +#define MSI_INT_MASK_CLR 0x14 #define PCIE_EXT_CFG_DATA 0x8000 @@ -132,6 +140,8 @@ /* PCIe parameters */ #define BRCM_NUM_PCIE_OUT_WINS 0x4 #define BRCM_INT_PCI_MSI_NR 32 +#define BRCM_INT_PCI_MSI_LEGACY_NR 8 +#define BRCM_INT_PCI_MSI_SHIFT 0 /* MSI target adresses */ #define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL @@ -246,6 +256,12 @@ struct brcm_msi { int irq; /* used indicates which MSI interrupts have been alloc'd */ unsigned long used; + bool legacy; + /* Some chips have MSIs in bits [31..24] of a shared register. */ + int legacy_shift; + int nr; /* No. of MSI available, depends on chip */ + /* This is the base pointer for interrupt status/set/clr regs */ + void __iomem *intr_base; }; /* Internal PCIe Host Controller Information.*/ @@ -265,6 +281,7 @@ struct brcm_pcie { struct reset_control *rescal; int num_memc; u64 memc_size[PCIE_BRCM_MAX_MEMC]; + u32 hw_rev; }; /* @@ -455,8 +472,10 @@ static void brcm_pcie_msi_isr(struct irq_desc *desc) msi = irq_desc_get_handler_data(desc); dev = msi->dev; - status = readl(msi->base + PCIE_MSI_INTR2_STATUS); - for_each_set_bit(bit, &status, BRCM_INT_PCI_MSI_NR) { + status = readl(msi->intr_base + MSI_INT_STATUS); + status >>= msi->legacy_shift; + + for_each_set_bit(bit, &status, msi->nr) { virq = irq_find_mapping(msi->inner_domain, bit); if (virq) generic_handle_irq(virq); @@ -473,7 +492,7 @@ static void brcm_msi_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) msg->address_lo = lower_32_bits(msi->target_addr); msg->address_hi = upper_32_bits(msi->target_addr); - msg->data = (0xffff & PCIE_MISC_MSI_DATA_CONFIG_VAL) | data->hwirq; + msg->data = (0xffff & PCIE_MISC_MSI_DATA_CONFIG_VAL_32) | data->hwirq; } static int brcm_msi_set_affinity(struct irq_data *irq_data, @@ -485,8 +504,9 @@ static int brcm_msi_set_affinity(struct irq_data *irq_data, static void brcm_msi_ack_irq(struct irq_data *data) { struct brcm_msi *msi = irq_data_get_irq_chip_data(data); + const int shift_amt = data->hwirq + msi->legacy_shift; - writel(1 << data->hwirq, msi->base + PCIE_MSI_INTR2_CLR); + writel(1 << shift_amt, msi->intr_base + MSI_INT_CLR); } @@ -502,7 +522,7 @@ static int brcm_msi_alloc(struct brcm_msi *msi) int hwirq; mutex_lock(&msi->lock); - hwirq = bitmap_find_free_region(&msi->used, BRCM_INT_PCI_MSI_NR, 0); + hwirq = bitmap_find_free_region(&msi->used, msi->nr, 0); mutex_unlock(&msi->lock); return hwirq; @@ -551,8 +571,7 @@ static int brcm_allocate_domains(struct brcm_msi *msi) struct fwnode_handle *fwnode = of_node_to_fwnode(msi->np); struct device *dev = msi->dev; - msi->inner_domain = irq_domain_add_linear(NULL, BRCM_INT_PCI_MSI_NR, - &msi_domain_ops, msi); + msi->inner_domain = irq_domain_add_linear(NULL, msi->nr, &msi_domain_ops, msi); if (!msi->inner_domain) { dev_err(dev, "failed to create IRQ domain\n"); return -ENOMEM; @@ -589,7 +608,10 @@ static void brcm_msi_remove(struct brcm_pcie *pcie) static void brcm_msi_set_regs(struct brcm_msi *msi) { - writel(0xffffffff, msi->base + PCIE_MSI_INTR2_MASK_CLR); + u32 val = __GENMASK(31, msi->legacy_shift); + + writel(val, msi->intr_base + MSI_INT_MASK_CLR); + writel(val, msi->intr_base + MSI_INT_CLR); /* * The 0 bit of PCIE_MISC_MSI_BAR_CONFIG_LO is repurposed to MSI @@ -600,8 +622,8 @@ static void brcm_msi_set_regs(struct brcm_msi *msi) writel(upper_32_bits(msi->target_addr), msi->base + PCIE_MISC_MSI_BAR_CONFIG_HI); - writel(PCIE_MISC_MSI_DATA_CONFIG_VAL, - msi->base + PCIE_MISC_MSI_DATA_CONFIG); + val = msi->legacy ? PCIE_MISC_MSI_DATA_CONFIG_VAL_8 : PCIE_MISC_MSI_DATA_CONFIG_VAL_32; + writel(val, msi->base + PCIE_MISC_MSI_DATA_CONFIG); } static int brcm_pcie_enable_msi(struct brcm_pcie *pcie) @@ -626,6 +648,17 @@ static int brcm_pcie_enable_msi(struct brcm_pcie *pcie) msi->np = pcie->np; msi->target_addr = pcie->msi_target_addr; msi->irq = irq; + msi->legacy = pcie->hw_rev < BRCM_PCIE_HW_REV_33; + + if (msi->legacy) { + msi->intr_base = msi->base + PCIE_INTR2_CPU_BASE; + msi->nr = BRCM_INT_PCI_MSI_LEGACY_NR; + msi->legacy_shift = 24; + } else { + msi->intr_base = msi->base + PCIE_MSI_INTR2_BASE; + msi->nr = BRCM_INT_PCI_MSI_NR; + msi->legacy_shift = 0; + } ret = brcm_allocate_domains(msi); if (ret) @@ -888,12 +921,6 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie) tmp &= ~PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK; writel(tmp, base + PCIE_MISC_RC_BAR3_CONFIG_LO); - /* Mask all interrupts since we are not handling any yet */ - writel(0xffffffff, pcie->base + PCIE_MSI_INTR2_MASK_SET); - - /* clear any interrupts we find on boot */ - writel(0xffffffff, pcie->base + PCIE_MSI_INTR2_CLR); - if (pcie->gen) brcm_pcie_set_gen(pcie, pcie->gen); @@ -1237,6 +1264,8 @@ static int brcm_pcie_probe(struct platform_device *pdev) if (ret) goto fail; + pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION); + msi_np = of_parse_phandle(pcie->np, "msi-parent", 0); if (pci_msi_enabled() && msi_np == pcie->np) { ret = brcm_pcie_enable_msi(pcie); -- 2.17.1