Message ID | 20241029033915.423211-1-sughosh.ganu@linaro.org |
---|---|
State | New |
Headers | show |
Series | [RFC] apple: dart: add logic to allocate dva addresses | expand |
On Tue, 29 Oct 2024 at 09:09, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > 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@linaro.org> > --- > > Note: I have only build tested this on the m1 defconfig. NAK. To be discarded. > > 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 >
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++)
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@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(-)