From patchwork Fri Aug 18 14:57:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kishon Vijay Abraham I X-Patchwork-Id: 110413 Delivered-To: patch@linaro.org Received: by 10.182.109.195 with SMTP id hu3csp940742obb; Fri, 18 Aug 2017 08:02:42 -0700 (PDT) X-Received: by 10.84.247.15 with SMTP id n15mr10072724pll.287.1503068562154; Fri, 18 Aug 2017 08:02:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503068562; cv=none; d=google.com; s=arc-20160816; b=VQIE6bDO1XMbZhCgLdbr+oJgK7XQSKtoKZVbMMtuTpYuKCyH1AajE34UHHFJhblvrt QCWHKx3fEoar11TEIyvX2YeipC+74s2s+GUuY8wzGCoG6Tou9MhqYrIBpEn9P8iPabMv 40fATUGQTklhNkP7Y2dGBPrteWRxqCgxn2OOSxXWdaPXvHytYr3fJZsCxkKhEKmFGi3o GX7G/S0mKaJq8i9ACqaVfhonwhidMIOZjqJDasIRC7wjLQYNsQP5Qi0IqRD3F2G+qSup Q/MhfpNzXDoKvbqLGBmyxkFK0ZXeOd+zeSEDMNLgp3p0ILrBv02dp+jiDLiQ8axK3oSU r3zQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=3IGTlvcqweTZrzwfnzgI+mXLIRtZ+XMqRbmiWM7knrg=; b=nXHswqwuxO64BaAGp7iUVADKuz64bAgqxcXl/qbqTatgqbwjA8V9zwxYvUjNXigzCl FTBol+QoFf1pCRf7cgwzWOX4vuCtdpL6xwJ2oBce+tWP3snVesUwndMFU16qKSPx6IPR hAAydYIOYAUZKvRNmd5/4ffmC7bBn9FDPwO3Sz7DSZL+aQRyu7pIEgXJdhL/aismUgEs ilkhxbQJzVjTx42Pj72raPzyW9qHVPAawhIu5UXsifzuk4Za87GHJVzIQ3BRfnC57ISz wNMxroYhh8fJoDlNskqDsWysjwF8LvTnQlN1zJXp/xjj5J14u4OQlmOLbB4zKfj2PaHc 2o8A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=JKheMZmq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m37si4101794plg.553.2017.08.18.08.02.41; Fri, 18 Aug 2017 08:02:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=JKheMZmq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752249AbdHRO6n (ORCPT + 26 others); Fri, 18 Aug 2017 10:58:43 -0400 Received: from lelnx193.ext.ti.com ([198.47.27.77]:25681 "EHLO lelnx193.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752172AbdHRO6k (ORCPT ); Fri, 18 Aug 2017 10:58:40 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelnx193.ext.ti.com (8.15.1/8.15.1) with ESMTP id v7IEwZSS013884; Fri, 18 Aug 2017 09:58:35 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ti.com; s=ti-com-17Q1; t=1503068315; bh=v3Kd0UZENv6qrlNL8R0KqxP54rU8v41fz2xJEIHccr8=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=JKheMZmqwjk7tTkteWOvc4opwpv4cdKsakhf6FPFTeRxEBnCqjvzNVT8Knl44im2P Zydfc/bamn4gLaSY7+s7I+/s4fdHke309DOdJiR3yOXf3k+0x1WNCWq4RbLqpfnjW/ bSEzEUnZGTbeHYHoWx+LflocMl/Cfxi8aBuwA/70= Received: from DFLE101.ent.ti.com (dfle101.ent.ti.com [10.64.6.22]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id v7IEwZow012110; Fri, 18 Aug 2017 09:58:35 -0500 Received: from DFLE115.ent.ti.com (10.64.6.36) by DFLE101.ent.ti.com (10.64.6.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.845.34; Fri, 18 Aug 2017 09:58:35 -0500 Received: from DFLE101.ent.ti.com (10.64.6.22) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.845.34; Fri, 18 Aug 2017 09:58:34 -0500 Received: from dlep33.itg.ti.com (157.170.170.75) by DFLE101.ent.ti.com (10.64.6.22) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.845.34 via Frontend Transport; Fri, 18 Aug 2017 09:58:34 -0500 Received: from a0393678ub.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id v7IEwKk2023721; Fri, 18 Aug 2017 09:58:32 -0500 From: Kishon Vijay Abraham I To: Bjorn Helgaas CC: Joao Pinto , Arnd Bergmann , , , , , , Subject: [PATCH 04/18] PCI: endpoint: pci-epc-mem: Add support for configurable page size Date: Fri, 18 Aug 2017 20:27:56 +0530 Message-ID: <20170818145810.17649-5-kishon@ti.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170818145810.17649-1-kishon@ti.com> References: <20170818145810.17649-1-kishon@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org pci-epc-mem uses a page size equal to *PAGE_SIZE* (usually 4KB) to manage the address space. However certain platforms like TI's K2G has a restriction that this address space should be either divided into 1MB/2MB/4MB or 8MB sizes (Ref: 11.14.4.9.1 Outbound Address Translation in K2G TRM SPRUHY8F January 2016 – Revised May 2017). Add support to handle different page sizes here. Signed-off-by: Kishon Vijay Abraham I --- drivers/pci/endpoint/pci-epc-mem.c | 59 ++++++++++++++++++++++++++++++++------ include/linux/pci-epc.h | 8 +++++- 2 files changed, 57 insertions(+), 10 deletions(-) -- 2.11.0 diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c index 3a94cc1caf22..83b7d5d3fc3e 100644 --- a/drivers/pci/endpoint/pci-epc-mem.c +++ b/drivers/pci/endpoint/pci-epc-mem.c @@ -24,21 +24,54 @@ #include /** - * pci_epc_mem_init() - initialize the pci_epc_mem structure + * pci_epc_mem_get_order() - determine the allocation order of a memory size + * @mem: address space of the endpoint controller + * @size: the size for which to get the order + * + * Reimplement get_order() for mem->page_size since the generic get_order + * always gets order with a constant PAGE_SIZE. + */ +static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size) +{ + int order; + unsigned int page_shift = ilog2(mem->page_size); + + size--; + size >>= page_shift; +#if BITS_PER_LONG == 32 + order = fls(size); +#else + order = fls64(size); +#endif + return order; +} + +/** + * __pci_epc_mem_init() - initialize the pci_epc_mem structure * @epc: the EPC device that invoked pci_epc_mem_init * @phys_base: the physical address of the base * @size: the size of the address space + * @page_size: size of each page * * Invoke to initialize the pci_epc_mem structure used by the * endpoint functions to allocate mapped PCI address. */ -int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size) +int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size, + size_t page_size) { int ret; struct pci_epc_mem *mem; unsigned long *bitmap; - int pages = size >> PAGE_SHIFT; - int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); + unsigned int page_shift; + int pages; + int bitmap_size; + + if (page_size < PAGE_SIZE) + page_size = PAGE_SIZE; + + page_shift = ilog2(page_size); + pages = size >> page_shift; + bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); mem = kzalloc(sizeof(*mem), GFP_KERNEL); if (!mem) { @@ -54,6 +87,7 @@ int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size) mem->bitmap = bitmap; mem->phys_base = phys_base; + mem->page_size = page_size; mem->pages = pages; mem->size = size; @@ -67,7 +101,7 @@ int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size) err: return ret; } -EXPORT_SYMBOL_GPL(pci_epc_mem_init); +EXPORT_SYMBOL_GPL(__pci_epc_mem_init); /** * pci_epc_mem_exit() - cleanup the pci_epc_mem structure @@ -101,13 +135,17 @@ void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, int pageno; void __iomem *virt_addr; struct pci_epc_mem *mem = epc->mem; - int order = get_order(size); + unsigned int page_shift = ilog2(mem->page_size); + int order; + + size = ALIGN(size, mem->page_size); + order = pci_epc_mem_get_order(mem, size); pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order); if (pageno < 0) return NULL; - *phys_addr = mem->phys_base + (pageno << PAGE_SHIFT); + *phys_addr = mem->phys_base + (pageno << page_shift); virt_addr = ioremap(*phys_addr, size); if (!virt_addr) bitmap_release_region(mem->bitmap, pageno, order); @@ -129,11 +167,14 @@ void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr, void __iomem *virt_addr, size_t size) { int pageno; - int order = get_order(size); struct pci_epc_mem *mem = epc->mem; + unsigned int page_shift = ilog2(mem->page_size); + int order; iounmap(virt_addr); - pageno = (phys_addr - mem->phys_base) >> PAGE_SHIFT; + pageno = (phys_addr - mem->phys_base) >> page_shift; + size = ALIGN(size, mem->page_size); + order = pci_epc_mem_get_order(mem, size); bitmap_release_region(mem->bitmap, pageno, order); } EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr); diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index af5edbf3eea3..f7a04e1af112 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h @@ -62,11 +62,13 @@ struct pci_epc_ops { * @size: the size of the PCI address space * @bitmap: bitmap to manage the PCI address space * @pages: number of bits representing the address region + * @page_size: size of each page */ struct pci_epc_mem { phys_addr_t phys_base; size_t size; unsigned long *bitmap; + size_t page_size; int pages; }; @@ -98,6 +100,9 @@ struct pci_epc { #define devm_pci_epc_create(dev, ops) \ __devm_pci_epc_create((dev), (ops), THIS_MODULE) +#define pci_epc_mem_init(epc, phys_addr, size) \ + __pci_epc_mem_init((epc), (phys_addr), (size), PAGE_SIZE) + static inline void epc_set_drvdata(struct pci_epc *epc, void *data) { dev_set_drvdata(&epc->dev, data); @@ -135,7 +140,8 @@ void pci_epc_stop(struct pci_epc *epc); struct pci_epc *pci_epc_get(const char *epc_name); void pci_epc_put(struct pci_epc *epc); -int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size); +int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size, + size_t page_size); void pci_epc_mem_exit(struct pci_epc *epc); void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, phys_addr_t *phys_addr, size_t size);