From patchwork Mon May 22 16:39:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oza Pawandeep X-Patchwork-Id: 9741047 X-Patchwork-Delegate: bhelgaas@google.com 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 9AFEF60388 for ; Mon, 22 May 2017 16:41:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8E3E82854F for ; Mon, 22 May 2017 16:41:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8318C2871D; Mon, 22 May 2017 16:41:36 +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=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, 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 150DE2854F for ; Mon, 22 May 2017 16:41:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935954AbdEVQkD (ORCPT ); Mon, 22 May 2017 12:40:03 -0400 Received: from mail-pf0-f182.google.com ([209.85.192.182]:36359 "EHLO mail-pf0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934139AbdEVQj7 (ORCPT ); Mon, 22 May 2017 12:39:59 -0400 Received: by mail-pf0-f182.google.com with SMTP id m17so87441322pfg.3 for ; Mon, 22 May 2017 09:39:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=snTiGbuGAzqfk9+I+Hf1R6/W8lL7DAbbYGOiXhWAofE=; b=Kd6lpBBUK0c4DxZBa7PP2qOKCZqe2xZ5ttxiUKEfvWt1SpP5NMMnjXB8JVXqEd1gFO /RgboOU/yhVb0xZ+y/prlXoWnDM89Up/aolsD0J6YppQBP+RSffdIWKzuy2bZFLs4xEW ZWRTDcjzRV8GV7GtOLOGYE3fpmaF+2AB/6iz8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=snTiGbuGAzqfk9+I+Hf1R6/W8lL7DAbbYGOiXhWAofE=; b=sGLYqafblf5EQNZ7hD6xGkWM0ADc9tlKJBAGO4/MzPt6/Ge4CakvXbkGYAMXfp2L+9 7Epi5jnScbyGCj3Z0zaok95ujmrn/Fi23HivHKgdyidolCbCdKKv7R7+IU3bRP+EE4Qt Efw1dz4Zwemeq8KlEgTNA88L2qnWuS8jW62HtT1wHfuWwMDvCgFJKNGCfUsHQawnPSMb k4639mB+vdmd5NUmcPjJDQK/1AawCl90Fn2i0MdSZ0FKg3CyYzQc7c38VltJMGqsLI4i bPJ+PKUFWExz2kW0GNece8Toqgo8qLeYkboE9IN8bQeHOMC6e1a3dk3JVPzA1CyoRq6i wLQQ== X-Gm-Message-State: AODbwcBnElAAeOLMSSJZED+Ao8Tj4d3pInZeHqFVRcQ1wplX2jlMBV0x mNSl2I7j0WRQneAQ X-Received: by 10.84.232.76 with SMTP id f12mr30437486pln.101.1495471198251; Mon, 22 May 2017 09:39:58 -0700 (PDT) Received: from anjanavk-OptiPlex-7010.dhcp.avagotech.net ([192.19.237.250]) by smtp.gmail.com with ESMTPSA id x198sm26538853pgx.28.2017.05.22.09.39.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 22 May 2017 09:39:57 -0700 (PDT) From: Oza Pawandeep To: Joerg Roedel , Robin Murphy Cc: iommu@lists.linux-foundation.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, bcm-kernel-feedback-list@broadcom.com, Oza Pawandeep , Oza Pawandeep Subject: [PATCH v7 1/3] OF/PCI: Export inbound memory interface to PCI RC drivers. Date: Mon, 22 May 2017 22:09:40 +0530 Message-Id: <1495471182-12490-2-git-send-email-oza.oza@broadcom.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1495471182-12490-1-git-send-email-oza.oza@broadcom.com> References: <1495471182-12490-1-git-send-email-oza.oza@broadcom.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The patch exports interface to PCIe RC drivers so that, Drivers can get their inbound memory configuration. It provides basis for IOVA reservations for inbound memory holes, if RC is not capable of addressing all the host memory, Specifically when IOMMU is enabled and on ARMv8 where 64bit IOVA could be allocated. It handles multiple inbound windows, and returns resources, and is left to the caller, how it wants to use them. Signed-off-by: Oza Pawandeep diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index c9d4d3a..20cf527 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c @@ -283,6 +283,102 @@ int of_pci_get_host_bridge_resources(struct device_node *dev, return err; } EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources); + +/** + * of_pci_get_dma_ranges - Parse PCI host bridge inbound resources from DT + * @np: device node of the host bridge having the dma-ranges property + * @resources: list where the range of resources will be added after DT parsing + * + * It is the caller's job to free the @resources list. + * + * This function will parse the "dma-ranges" property of a + * PCI host bridge device node and setup the resource mapping based + * on its content. + * + * It returns zero if the range parsing has been successful or a standard error + * value if it failed. + */ + +int of_pci_get_dma_ranges(struct device_node *dn, struct list_head *resources) +{ + struct device_node *node = of_node_get(dn); + int rlen; + int pna = of_n_addr_cells(node); + const int na = 3, ns = 2; + int np = pna + na + ns; + int ret = 0; + struct resource *res; + const u32 *dma_ranges; + struct of_pci_range range; + + if (!node) + return -EINVAL; + + while (1) { + dma_ranges = of_get_property(node, "dma-ranges", &rlen); + + /* Ignore empty ranges, they imply no translation required. */ + if (dma_ranges && rlen > 0) + break; + + /* no dma-ranges, they imply no translation required. */ + if (!dma_ranges) + break; + + node = of_get_next_parent(node); + + if (!node) + break; + } + + if (!dma_ranges) { + pr_debug("pcie device has no dma-ranges defined for node(%s)\n", + dn->full_name); + ret = -EINVAL; + goto out; + } + + while ((rlen -= np * 4) >= 0) { + range.pci_space = be32_to_cpup((const __be32 *) &dma_ranges[0]); + range.pci_addr = of_read_number(dma_ranges + 1, ns); + range.cpu_addr = of_translate_dma_address(node, + dma_ranges + na); + range.size = of_read_number(dma_ranges + pna + na, ns); + range.flags = IORESOURCE_MEM; + + dma_ranges += np; + + /* + * If we failed translation or got a zero-sized region + * then skip this range. + */ + if (range.cpu_addr == OF_BAD_ADDR || range.size == 0) + continue; + + res = kzalloc(sizeof(struct resource), GFP_KERNEL); + if (!res) { + ret = -ENOMEM; + goto parse_failed; + } + + ret = of_pci_range_to_resource(&range, dn, res); + if (ret) { + kfree(res); + continue; + } + + pci_add_resource_offset(resources, res, + res->start - range.pci_addr); + } + return ret; + +parse_failed: + pci_free_resource_list(resources); +out: + of_node_put(node); + return ret; +} +EXPORT_SYMBOL_GPL(of_pci_get_dma_ranges); #endif /* CONFIG_OF_ADDRESS */ /** diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index 518c8d2..0eafe86 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h @@ -76,6 +76,7 @@ static inline void of_pci_check_probe_only(void) { } int of_pci_get_host_bridge_resources(struct device_node *dev, unsigned char busno, unsigned char bus_max, struct list_head *resources, resource_size_t *io_base); +int of_pci_get_dma_ranges(struct device_node *np, struct list_head *resources); #else static inline int of_pci_get_host_bridge_resources(struct device_node *dev, unsigned char busno, unsigned char bus_max, @@ -83,6 +84,12 @@ static inline int of_pci_get_host_bridge_resources(struct device_node *dev, { return -EINVAL; } + +static inline int of_pci_get_dma_ranges(struct device_node *np, + struct list_head *resources) +{ + return -EINVAL; +} #endif #endif