From: Loic Pallardy <loic.pallardy@st.com> To: bjorn.andersson@linaro.org, ohad@wizery.com, lee.jones@linaro.org Cc: loic.pallardy@st.com, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] remoteproc: core: Add fixed memory region support Date: Fri, 26 Aug 2016 22:19:55 +0200 [thread overview] Message-ID: <1472242795-23970-3-git-send-email-loic.pallardy@st.com> (raw) In-Reply-To: <1472242795-23970-1-git-send-email-loic.pallardy@st.com> 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 <loic.pallardy@st.com> --- drivers/remoteproc/remoteproc_core.c | 61 ++++++++++++++++++++++++++---------- include/linux/remoteproc.h | 4 +++ 2 files changed, 49 insertions(+), 16 deletions(-) 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; }; /** -- 1.9.1
WARNING: multiple messages have this Message-ID (diff)
From: Loic Pallardy <loic.pallardy@st.com> To: <bjorn.andersson@linaro.org>, <ohad@wizery.com>, <lee.jones@linaro.org> Cc: <loic.pallardy@st.com>, <linux-remoteproc@vger.kernel.org>, <linux-kernel@vger.kernel.org> Subject: [PATCH 2/2] remoteproc: core: Add fixed memory region support Date: Fri, 26 Aug 2016 22:19:55 +0200 [thread overview] Message-ID: <1472242795-23970-3-git-send-email-loic.pallardy@st.com> (raw) In-Reply-To: <1472242795-23970-1-git-send-email-loic.pallardy@st.com> 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 <loic.pallardy@st.com> --- drivers/remoteproc/remoteproc_core.c | 61 ++++++++++++++++++++++++++---------- include/linux/remoteproc.h | 4 +++ 2 files changed, 49 insertions(+), 16 deletions(-) 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; }; /** -- 1.9.1
next prev parent reply other threads:[~2016-08-26 20:19 UTC|newest] Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-08-26 20:19 [PATCH 0/2] Remoteproc: Add predefined coprocessor memory mapping support Loic Pallardy 2016-08-26 20:19 ` Loic Pallardy 2016-08-26 20:19 ` [PATCH 1/2] remoteproc: Modify FW_RSC_ADDR_ANY definition Loic Pallardy 2016-08-26 20:19 ` Loic Pallardy 2016-08-26 20:19 ` Loic Pallardy [this message] 2016-08-26 20:19 ` [PATCH 2/2] remoteproc: core: Add fixed memory region support Loic Pallardy 2016-08-27 0:32 ` Bjorn Andersson 2016-08-29 8:09 ` loic pallardy 2016-08-29 8:09 ` loic pallardy 2016-08-30 23:13 ` Suman Anna 2016-08-30 23:13 ` Suman Anna 2016-08-31 16:05 ` loic pallardy 2016-08-31 16:05 ` loic pallardy 2016-08-31 16:37 ` Bjorn Andersson 2016-08-31 16:55 ` Suman Anna 2016-08-31 16:55 ` Suman Anna
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1472242795-23970-3-git-send-email-loic.pallardy@st.com \ --to=loic.pallardy@st.com \ --cc=bjorn.andersson@linaro.org \ --cc=lee.jones@linaro.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-remoteproc@vger.kernel.org \ --cc=ohad@wizery.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.