From patchwork Fri Aug 26 20:19:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Loic Pallardy X-Patchwork-Id: 74850 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp563140qga; Fri, 26 Aug 2016 14:14:39 -0700 (PDT) X-Received: by 10.98.155.17 with SMTP id r17mr9622658pfd.24.1472246079015; Fri, 26 Aug 2016 14:14:39 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id wv6si23027786pab.263.2016.08.26.14.14.38; Fri, 26 Aug 2016 14:14:39 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754187AbcHZVOY (ORCPT + 27 others); Fri, 26 Aug 2016 17:14:24 -0400 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:24343 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751554AbcHZVOU (ORCPT ); Fri, 26 Aug 2016 17:14:20 -0400 Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx08-00178001.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u7QKGQ4M026885; Fri, 26 Aug 2016 22:20:12 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-.pphosted.com with ESMTP id 252124h2jg-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Fri, 26 Aug 2016 22:20:12 +0200 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id A217B31; Fri, 26 Aug 2016 20:20:11 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas24.st.com [10.75.90.94]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 86FD34E38; Fri, 26 Aug 2016 20:20:11 +0000 (GMT) Received: from localhost (10.129.7.211) by webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.279.2; Fri, 26 Aug 2016 22:20:11 +0200 From: Loic Pallardy To: , , CC: , , Subject: [PATCH 2/2] remoteproc: core: Add fixed memory region support Date: Fri, 26 Aug 2016 22:19:55 +0200 Message-ID: <1472242795-23970-3-git-send-email-loic.pallardy@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1472242795-23970-1-git-send-email-loic.pallardy@st.com> References: <1472242795-23970-1-git-send-email-loic.pallardy@st.com> MIME-Version: 1.0 X-Originating-IP: [10.129.7.211] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-08-26_14:, , signatures=0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some coprocessors request fixed memory mapping for firmware execution and associated communication linked. Memory resources are defined in firmware resource table. Resource address different from 0x0 and 0xFFFFFFFF is considered as predefined and already reserved at system level. In that case, remoteproc core doesn't need to perform any allocation. Memory region access can be managed using memremap/memunmap functions Signed-off-by: Loic Pallardy --- drivers/remoteproc/remoteproc_core.c | 61 ++++++++++++++++++++++++++---------- include/linux/remoteproc.h | 4 +++ 2 files changed, 49 insertions(+), 16 deletions(-) -- 1.9.1 diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 18f4286..0ddbb92 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -213,13 +213,25 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i) /* actual size of vring (in bytes) */ size = PAGE_ALIGN(vring_size(rvring->len, rvring->align)); - /* - * Allocate non-cacheable memory for the vring. In the future - * this call will also configure the IOMMU for us - */ - va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL); + rsc = (void *)rproc->table_ptr + rvdev->rsc_offset; + + /* check if specific memory region requested by firmware */ + if (rsc->vring[i].da != 0 && rsc->vring[i].da != FW_RSC_ADDR_ANY) { + va = memremap(rsc->vring[i].da, size, MEMREMAP_WC); + rvring->dma = rsc->vring[i].da; + rvring->memmap = true; + } else { + /* + * Allocate non-cacheable memory for the vring. In the future + * this call will also configure the IOMMU for us + */ + va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL); + rvring->dma = dma; + rsc->vring[i].da = dma; + } + if (!va) { - dev_err(dev->parent, "dma_alloc_coherent failed\n"); + dev_err(dev->parent, "Failed to get valid ving[%d] va\n", i); return -EINVAL; } @@ -231,7 +243,10 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i) ret = idr_alloc(&rproc->notifyids, rvring, 0, 0, GFP_KERNEL); if (ret < 0) { dev_err(dev, "idr_alloc failed: %d\n", ret); - dma_free_coherent(dev->parent, size, va, dma); + if (rvring->memmap) + memunmap(rvring->va); + else + dma_free_coherent(dev->parent, size, va, dma); return ret; } notifyid = ret; @@ -240,7 +255,6 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i) i, va, &dma, size, notifyid); rvring->va = va; - rvring->dma = dma; rvring->notifyid = notifyid; /* @@ -249,8 +263,6 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i) * set up the iommu. In this case the device address (da) will * hold the physical address and not the device address. */ - rsc = (void *)rproc->table_ptr + rvdev->rsc_offset; - rsc->vring[i].da = dma; rsc->vring[i].notifyid = notifyid; return 0; } @@ -293,7 +305,11 @@ void rproc_free_vring(struct rproc_vring *rvring) int idx = rvring->rvdev->vring - rvring; struct fw_rsc_vdev *rsc; - dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma); + if (rvring->memmap) + memunmap(rvring->va); + else + dma_free_coherent(rproc->dev.parent, size, rvring->va, + rvring->dma); idr_remove(&rproc->notifyids, rvring->notifyid); /* reset resource entry info */ @@ -585,7 +601,15 @@ static int rproc_handle_carveout(struct rproc *rproc, if (!carveout) return -ENOMEM; - va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL); + /* check if specific memory region requested by firmware */ + if (rsc->pa != 0 && rsc->pa != FW_RSC_ADDR_ANY) { + va = memremap(rsc->pa, rsc->len, MEMREMAP_WC); + carveout->memmap = true; + dma = rsc->pa; + } else { + va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL); + rsc->pa = dma; + } if (!va) { dev_err(dev->parent, "failed to allocate dma memory: len 0x%x\n", rsc->len); @@ -659,7 +683,6 @@ static int rproc_handle_carveout(struct rproc *rproc, * In this case, the device address and the physical address * are the same. */ - rsc->pa = dma; carveout->va = va; carveout->len = rsc->len; @@ -673,7 +696,10 @@ static int rproc_handle_carveout(struct rproc *rproc, free_mapping: kfree(mapping); dma_free: - dma_free_coherent(dev->parent, rsc->len, va, dma); + if (carveout->memmap) + memunmap(va); + else + dma_free_coherent(dev->parent, rsc->len, va, dma); free_carv: kfree(carveout); return ret; @@ -780,8 +806,11 @@ static void rproc_resource_cleanup(struct rproc *rproc) /* clean up carveout allocations */ list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) { - dma_free_coherent(dev->parent, entry->len, entry->va, - entry->dma); + if (entry->memmap) + memunmap(entry->va); + else + dma_free_coherent(dev->parent, entry->len, entry->va, + entry->dma); list_del(&entry->node); kfree(entry); } diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 80e1cba..ff1fb59 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -312,6 +312,7 @@ struct fw_rsc_vdev { * @len: length, in bytes * @da: device address * @priv: associated data + * @memmap: true if memory is memremapped * @node: list node */ struct rproc_mem_entry { @@ -320,6 +321,7 @@ struct rproc_mem_entry { int len; u32 da; void *priv; + bool memmap; struct list_head node; }; @@ -458,6 +460,7 @@ struct rproc { * @notifyid: rproc-specific unique vring index * @rvdev: remote vdev * @vq: the virtqueue of this vring + * @memmap: true if memory is memremapped */ struct rproc_vring { void *va; @@ -468,6 +471,7 @@ struct rproc_vring { int notifyid; struct rproc_vdev *rvdev; struct virtqueue *vq; + bool memmap; }; /**