[RFC PATCH] apple: dart: add logic to allocate dva addresses

Sughosh Ganu sughosh.ganu at linaro.org
Tue Oct 29 04:39:15 CET 2024


The Apple IOMMU driver uses LMB API's to allocate virtual addresses
for IO devices. These virtual addresses fall in the first 4GB address
range. Currently, the driver obtains these virtual addresses through
the LMB API's. This no longer works with the global LMB map. Add a
function apple_dart_dvaalloc() which mimics what was being done by the
LMB allocation function.

Signed-off-by: Sughosh Ganu <sughosh.ganu at linaro.org>
---

Note: I have only build tested this on the m1 defconfig.

 drivers/iommu/apple_dart.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/apple_dart.c b/drivers/iommu/apple_dart.c
index 611ac7cd6de..8e2acf50a06 100644
--- a/drivers/iommu/apple_dart.c
+++ b/drivers/iommu/apple_dart.c
@@ -6,7 +6,6 @@
 #include <cpu_func.h>
 #include <dm.h>
 #include <iommu.h>
-#include <lmb.h>
 #include <memalign.h>
 #include <asm/io.h>
 
@@ -75,6 +74,7 @@ struct apple_dart_priv {
 
 	dma_addr_t dvabase;
 	dma_addr_t dvaend;
+	dma_addr_t dvaalloc;
 
 	int nsid;
 	int nttbr;
@@ -109,6 +109,21 @@ static void apple_dart_t8110_flush_tlb(struct apple_dart_priv *priv)
 		continue;
 }
 
+static dma_addr_t apple_dart_dvaalloc(struct udevice *dev, phys_size_t size)
+{
+	dma_addr_t dva;
+	struct apple_dart_priv *priv = dev_get_priv(dev);
+
+	dva = priv->dvaalloc - size;
+	dva &= ~(DART_PAGE_SIZE - 1);
+
+	assert(dva > priv->dvabase);
+
+	priv->dvaalloc = dva;
+
+	return priv->dvaalloc;
+}
+
 static dma_addr_t apple_dart_map(struct udevice *dev, void *addr, size_t size)
 {
 	struct apple_dart_priv *priv = dev_get_priv(dev);
@@ -123,7 +138,7 @@ static dma_addr_t apple_dart_map(struct udevice *dev, void *addr, size_t size)
 	off = (phys_addr_t)addr - paddr;
 	psize = ALIGN(size + off, DART_PAGE_SIZE);
 
-	dva = lmb_alloc(psize, DART_PAGE_SIZE);
+	dva = apple_dart_dvaalloc(dev, psize);
 
 	idx = dva / DART_PAGE_SIZE;
 	for (i = 0; i < psize / DART_PAGE_SIZE; i++) {
@@ -158,8 +173,6 @@ static void apple_dart_unmap(struct udevice *dev, dma_addr_t addr, size_t size)
 	flush_dcache_range((unsigned long)&priv->l2[idx],
 			   (unsigned long)&priv->l2[idx + i]);
 	priv->flush_tlb(priv);
-
-	lmb_free(dva, psize);
 }
 
 static struct iommu_ops apple_dart_ops = {
@@ -211,8 +224,7 @@ static int apple_dart_probe(struct udevice *dev)
 
 	priv->dvabase = DART_PAGE_SIZE;
 	priv->dvaend = SZ_4G - DART_PAGE_SIZE;
-
-	lmb_add(priv->dvabase, priv->dvaend - priv->dvabase);
+	priv->dvaalloc = priv->dvaend;
 
 	/* Disable translations. */
 	for (sid = 0; sid < priv->nsid; sid++)
-- 
2.34.1



More information about the U-Boot mailing list