]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
iommu: apple: Manage IOVA separately from global LMB mem map
authorJanne Grunau <j@jannau.net>
Mon, 11 Nov 2024 06:56:34 +0000 (07:56 +0100)
committerTom Rini <trini@konsulko.com>
Mon, 11 Nov 2024 13:26:44 +0000 (07:26 -0600)
There is no overlap between the IOVA space managed by the iommu (here
the 32-bit address space) and physical RAM on Apple silicon systems. The
RAM starts at 0x10_0000_0000 or 0x100_0000_0000 so it's not possible to
manage the IOVA with the global memory LMB and use 1:1 translation.
In addition each device has its own iommu and does not need to share the
address space with all other devices. This should not be problem for
u-boot's limited use and hardware support.
Restore the private per instance LMB IOVA map.

Fixes: ed17a33fed2 ("lmb: make LMB memory map persistent and global")
Signed-off-by: Janne Grunau <j@jannau.net>
drivers/iommu/apple_dart.c

index 611ac7cd6deb4fccd45ccfe8cbb9b3e36e2af753..3e9e7819e517b8fe62b9e429b7a8ca3eca29741d 100644 (file)
@@ -73,6 +73,8 @@ struct apple_dart_priv {
        u64 *l1, *l2;
        int bypass, shift;
 
+       struct lmb io_lmb;
+
        dma_addr_t dvabase;
        dma_addr_t dvaend;
 
@@ -123,7 +125,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 = io_lmb_alloc(&priv->io_lmb, psize, DART_PAGE_SIZE);
 
        idx = dva / DART_PAGE_SIZE;
        for (i = 0; i < psize / DART_PAGE_SIZE; i++) {
@@ -159,7 +161,7 @@ static void apple_dart_unmap(struct udevice *dev, dma_addr_t addr, size_t size)
                           (unsigned long)&priv->l2[idx + i]);
        priv->flush_tlb(priv);
 
-       lmb_free(dva, psize);
+       io_lmb_free(&priv->io_lmb, dva, psize);
 }
 
 static struct iommu_ops apple_dart_ops = {
@@ -173,7 +175,7 @@ static int apple_dart_probe(struct udevice *dev)
        dma_addr_t addr;
        phys_addr_t l2;
        int ntte, nl1, nl2;
-       int sid, i;
+       int ret, sid, i;
        u32 params2, params4;
 
        priv->base = dev_read_addr_ptr(dev);
@@ -212,7 +214,13 @@ 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);
+       ret = io_lmb_setup(&priv->io_lmb);
+       if (ret)
+               return ret;
+       ret = io_lmb_add(&priv->io_lmb, priv->dvabase,
+                        priv->dvaend - priv->dvabase);
+       if (ret)
+               return -EINVAL;
 
        /* Disable translations. */
        for (sid = 0; sid < priv->nsid; sid++)
@@ -294,6 +302,8 @@ static int apple_dart_remove(struct udevice *dev)
        }
        priv->flush_tlb(priv);
 
+       io_lmb_teardown(&priv->io_lmb);
+
        return 0;
 }