From patchwork Fri Oct 13 16:09:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niklas Cassel X-Patchwork-Id: 10005217 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 63F6E60360 for ; Fri, 13 Oct 2017 16:10:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 50654290D4 for ; Fri, 13 Oct 2017 16:10:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4545A290D7; Fri, 13 Oct 2017 16:10:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AB5A1290D4 for ; Fri, 13 Oct 2017 16:10:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751712AbdJMQK2 (ORCPT ); Fri, 13 Oct 2017 12:10:28 -0400 Received: from bastet.se.axis.com ([195.60.68.11]:52255 "EHLO bastet.se.axis.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751455AbdJMQJo (ORCPT ); Fri, 13 Oct 2017 12:09:44 -0400 Received: from localhost (localhost [127.0.0.1]) by bastet.se.axis.com (Postfix) with ESMTP id 30048185FF; Fri, 13 Oct 2017 18:09:43 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bastet.se.axis.com Received: from bastet.se.axis.com ([IPv6:::ffff:127.0.0.1]) by localhost (bastet.se.axis.com [::ffff:127.0.0.1]) (amavisd-new, port 10024) with LMTP id ndngnZ5JeHXa; Fri, 13 Oct 2017 18:09:42 +0200 (CEST) Received: from boulder03.se.axis.com (boulder03.se.axis.com [10.0.8.17]) by bastet.se.axis.com (Postfix) with ESMTPS id EDA67185C7; Fri, 13 Oct 2017 18:09:41 +0200 (CEST) Received: from boulder03.se.axis.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D9B901E078; Fri, 13 Oct 2017 18:09:41 +0200 (CEST) Received: from boulder03.se.axis.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CD8A71E076; Fri, 13 Oct 2017 18:09:41 +0200 (CEST) Received: from seth.se.axis.com (unknown [10.0.2.172]) by boulder03.se.axis.com (Postfix) with ESMTP; Fri, 13 Oct 2017 18:09:41 +0200 (CEST) Received: from lnxartpec1.se.axis.com (lnxartpec1.se.axis.com [10.88.4.10]) by seth.se.axis.com (Postfix) with ESMTP id BFB5057C; Fri, 13 Oct 2017 18:09:41 +0200 (CEST) Received: by lnxartpec1.se.axis.com (Postfix, from userid 20283) id BC3C8401A0; Fri, 13 Oct 2017 18:09:41 +0200 (CEST) From: Niklas Cassel To: Kishon Vijay Abraham I , Bjorn Helgaas , Niklas Cassel , Jesper Nilsson , Jingoo Han , Joao Pinto Cc: linux-omap@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@axis.com Subject: [PATCH 09/10] PCI: dwc: make cpu_addr_fixup take struct dw_pcie as argument Date: Fri, 13 Oct 2017 18:09:12 +0200 Message-Id: <20171013160914.3220-10-niklas.cassel@axis.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171013160914.3220-1-niklas.cassel@axis.com> References: <20171013160914.3220-1-niklas.cassel@axis.com> X-TM-AS-GCONF: 00 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There is no need to hard code the cpu to bus fixup address. By calculating the sum of sizes of config, io and mem, from device tree, we know how big the PCIe window is. The bus address has to be inside of this range, so all bits in the cpu address that are higher than this range, are the ones that we need to clear to get the local bus address. Also for ARTPEC-7, hard coding the cpu fixup address is not possible, since it uses a High Address Bits Look Up Table, which means that it can, at runtime, map the PCIe window to an arbitrary address in the 32-bit address space. This also fixes a bug for ARTPEC-6, where the cpu_fixup_address previously masked one bit too many. (Another reason why it should be calculated from device tree.) Signed-off-by: Niklas Cassel --- drivers/pci/dwc/pci-dra7xx.c | 2 +- drivers/pci/dwc/pcie-artpec6.c | 42 +++++++++++++++++++++++++++++++++++---- drivers/pci/dwc/pcie-designware.c | 2 +- drivers/pci/dwc/pcie-designware.h | 2 +- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c index 34427a6a15af..a93bafc72fa0 100644 --- a/drivers/pci/dwc/pci-dra7xx.c +++ b/drivers/pci/dwc/pci-dra7xx.c @@ -109,7 +109,7 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset, writel(value, pcie->base + offset); } -static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr) +static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr) { return pci_addr & DRA7XX_CPU_TO_BUS_ADDR; } diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c index 21ea9ffef784..1e113dbea1da 100644 --- a/drivers/pci/dwc/pcie-artpec6.c +++ b/drivers/pci/dwc/pcie-artpec6.c @@ -32,6 +32,7 @@ struct artpec6_pcie { struct regmap *regmap; /* DT axis,syscon-pcie */ void __iomem *phy_base; /* DT phy */ enum dw_pcie_device_mode mode; + u64 cpu_fixup_mask; }; struct artpec_pcie_of_data { @@ -69,8 +70,6 @@ static const struct of_device_id artpec6_pcie_of_match[]; #define PHY_STATUS 0x118 #define PHY_COSPLLLOCK BIT(0) -#define ARTPEC6_CPU_TO_BUS_ADDR GENMASK(27, 0) - static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset) { u32 val; @@ -84,9 +83,42 @@ static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u regmap_write(artpec6_pcie->regmap, offset, val); } -static u64 artpec6_pcie_cpu_addr_fixup(u64 pci_addr) +static void artpec6_pcie_calc_cpu_fixup_mask(struct artpec6_pcie *artpec6_pcie) { - return pci_addr & ARTPEC6_CPU_TO_BUS_ADDR; + struct dw_pcie *pci = artpec6_pcie->pci; + struct pcie_port *pp = &pci->pp; + struct dw_pcie_ep *ep = &pci->ep; + u64 size; + u64 mask; + int msb; + + switch (artpec6_pcie->mode) { + case DW_PCIE_RC_TYPE: + size = pp->cfg0_size + pp->cfg1_size + pp->io_size + + pp->mem_size; + break; + case DW_PCIE_EP_TYPE: + size = ep->addr_size; + break; + default: + dev_err(pci->dev, "UNKNOWN device type\n"); + return; + } + /* Calculate the mask (which can have potential holes). */ + mask = size - 1; + /* Find the mask's msb. */ + msb = fls64(mask); + /* Use the msb to generate a new mask without any holes. */ + mask = (1ULL << msb) - 1; + artpec6_pcie->cpu_fixup_mask = mask; + dev_dbg(pci->dev, "Using cpu fixup mask: 0x%llx\n", mask); +} + +static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr) +{ + struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); + + return pci_addr & artpec6_pcie->cpu_fixup_mask; } static void artpec6_pcie_init_phy(struct artpec6_pcie *artpec6_pcie) @@ -190,6 +222,7 @@ static int artpec6_pcie_host_init(struct pcie_port *pp) struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); + artpec6_pcie_calc_cpu_fixup_mask(artpec6_pcie); artpec6_pcie_assert_core_reset(artpec6_pcie); artpec6_pcie_init_phy(artpec6_pcie); artpec6_pcie_deassert_core_reset(artpec6_pcie); @@ -231,6 +264,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep) struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); enum pci_barno bar; + artpec6_pcie_calc_cpu_fixup_mask(artpec6_pcie); artpec6_pcie_assert_core_reset(artpec6_pcie); artpec6_pcie_init_phy(artpec6_pcie); artpec6_pcie_deassert_core_reset(artpec6_pcie); diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c index 88abdddee2ad..800be7a4f087 100644 --- a/drivers/pci/dwc/pcie-designware.c +++ b/drivers/pci/dwc/pcie-designware.c @@ -149,7 +149,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type, u32 retries, val; if (pci->ops->cpu_addr_fixup) - cpu_addr = pci->ops->cpu_addr_fixup(cpu_addr); + cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr); if (pci->iatu_unroll_enabled) { dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr, diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h index f56d040afde4..897e190f8e24 100644 --- a/drivers/pci/dwc/pcie-designware.h +++ b/drivers/pci/dwc/pcie-designware.h @@ -203,7 +203,7 @@ struct dw_pcie_ep { }; struct dw_pcie_ops { - u64 (*cpu_addr_fixup)(u64 cpu_addr); + u64 (*cpu_addr_fixup)(struct dw_pcie *pcie, u64 cpu_addr); u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, size_t size); void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,