All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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: link
Be 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.