Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1939413c authored by Charan Teja Reddy's avatar Charan Teja Reddy
Browse files

arm: dma-mapping: add dma mapper for io-pgtable-fast for 32 bit



io-pgtable-fast was implemented to achieve
better performance for IOMMU map/un-map. Add
DMA API support that goes through io-pgtable-fast
for 32 bit targets.

Change-Id:I3d0560a4331f6b7b87c70d0885df11d12cb1d6ec
Signed-off-by: default avatarCharan Teja Reddy <charante@codeaurora.org>
parent d664828b
Loading
Loading
Loading
Loading
+17 −1
Original line number Original line Diff line number Diff line
@@ -178,10 +178,26 @@ extern void __cpuc_flush_dcache_area(void *, size_t);
 * is visible to DMA, or data written by DMA to system memory is
 * is visible to DMA, or data written by DMA to system memory is
 * visible to the CPU.
 * visible to the CPU.
 */
 */
extern void __dma_map_area(const void *addr, size_t size, int dir);
extern void __dma_unmap_area(const void *addr, size_t size, int dir);
extern void dmac_inv_range(const void *start, const void *end);
extern void dmac_inv_range(const void *start, const void *end);
extern void dmac_clean_range(const void *start, const void *end);
extern void dmac_clean_range(const void *start, const void *end);
extern void dmac_flush_range(const void *, const void *);
extern void dmac_flush_range(const void *start, const void *end);


static inline void __dma_inv_area(const void *start, size_t len)
{
	dmac_inv_range(start, start + len);
}

static inline void __dma_clean_area(const void *start, size_t len)
{
	dmac_clean_range(start, start + len);
}

static inline void __dma_flush_area(const void *start, size_t len)
{
	dmac_flush_range(start, start + len);
}
#endif
#endif


/*
/*
+4 −0
Original line number Original line Diff line number Diff line
@@ -8,12 +8,14 @@
#include <linux/scatterlist.h>
#include <linux/scatterlist.h>
#include <linux/dma-debug.h>
#include <linux/dma-debug.h>
#include <linux/kref.h>
#include <linux/kref.h>
#include <linux/dma-mapping-fast.h>


#define ARM_MAPPING_ERROR		(~(dma_addr_t)0x0)
#define ARM_MAPPING_ERROR		(~(dma_addr_t)0x0)


struct dma_iommu_mapping {
struct dma_iommu_mapping {
	/* iommu specific data */
	/* iommu specific data */
	struct iommu_domain	*domain;
	struct iommu_domain	*domain;
	const struct dma_map_ops *ops;


	unsigned long		**bitmaps;	/* array of bitmaps */
	unsigned long		**bitmaps;	/* array of bitmaps */
	unsigned int		nr_bitmaps;	/* nr of elements in array */
	unsigned int		nr_bitmaps;	/* nr of elements in array */
@@ -24,6 +26,8 @@ struct dma_iommu_mapping {


	spinlock_t		lock;
	spinlock_t		lock;
	struct kref		kref;
	struct kref		kref;

	struct dma_fast_smmu_mapping *fast;
};
};


struct dma_iommu_mapping *
struct dma_iommu_mapping *
+5 −0
Original line number Original line Diff line number Diff line
@@ -157,6 +157,11 @@ static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { }
#define dmac_flush_range		__glue(_CACHE,_dma_flush_range)
#define dmac_flush_range		__glue(_CACHE,_dma_flush_range)
#define dmac_inv_range			__glue(_CACHE, _dma_inv_range)
#define dmac_inv_range			__glue(_CACHE, _dma_inv_range)
#define dmac_clean_range		__glue(_CACHE, _dma_clean_range)
#define dmac_clean_range		__glue(_CACHE, _dma_clean_range)
#define dmac_map_area			__glue(_CACHE, _dma_map_area)
#define dmac_unmap_area			__glue(_CACHE, _dma_unmap_area)

#define __dma_map_area			dmac_map_area
#define __dma_unmap_area		dmac_unmap_area
#endif
#endif


#endif
#endif
+17 −2
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/vmalloc.h>
#include <linux/vmalloc.h>
#include <linux/sizes.h>
#include <linux/sizes.h>
#include <linux/cma.h>
#include <linux/cma.h>
#include <linux/dma-mapping-fast.h>


#include <asm/memory.h>
#include <asm/memory.h>
#include <asm/highmem.h>
#include <asm/highmem.h>
@@ -2336,6 +2337,7 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size)
		goto err4;
		goto err4;


	kref_init(&mapping->kref);
	kref_init(&mapping->kref);
	mapping->ops = &iommu_ops;
	return mapping;
	return mapping;
err4:
err4:
	kfree(mapping->bitmaps[0]);
	kfree(mapping->bitmaps[0]);
@@ -2351,9 +2353,15 @@ EXPORT_SYMBOL_GPL(arm_iommu_create_mapping);
static void release_iommu_mapping(struct kref *kref)
static void release_iommu_mapping(struct kref *kref)
{
{
	int i;
	int i;
	int is_fast = 0;

	struct dma_iommu_mapping *mapping =
	struct dma_iommu_mapping *mapping =
		container_of(kref, struct dma_iommu_mapping, kref);
		container_of(kref, struct dma_iommu_mapping, kref);


	iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_FAST, &is_fast);
	if (is_fast)
		fast_smmu_release_mapping(kref);

	iommu_domain_free(mapping->domain);
	iommu_domain_free(mapping->domain);
	for (i = 0; i < mapping->nr_bitmaps; i++)
	for (i = 0; i < mapping->nr_bitmaps; i++)
		kfree(mapping->bitmaps[i]);
		kfree(mapping->bitmaps[i]);
@@ -2419,7 +2427,14 @@ int arm_iommu_attach_device(struct device *dev,
			    struct dma_iommu_mapping *mapping)
			    struct dma_iommu_mapping *mapping)
{
{
	int err;
	int err;
	int s1_bypass = 0;
	int s1_bypass = 0, is_fast = 0;

	iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_FAST, &is_fast);
	if (is_fast) {
		err = fast_smmu_init_mapping(dev, mapping);
		if (err)
			return err;
	}


	err = __arm_iommu_attach_device(dev, mapping);
	err = __arm_iommu_attach_device(dev, mapping);
	if (err)
	if (err)
@@ -2428,7 +2443,7 @@ int arm_iommu_attach_device(struct device *dev,
	iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS,
	iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS,
					&s1_bypass);
					&s1_bypass);
	if (!s1_bypass)
	if (!s1_bypass)
		set_dma_ops(dev, &iommu_ops);
		set_dma_ops(dev, mapping->ops);
	return 0;
	return 0;
}
}
EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
+0 −3
Original line number Original line Diff line number Diff line
@@ -5,9 +5,6 @@
#include <asm/glue-cache.h>
#include <asm/glue-cache.h>


#ifndef MULTI_CACHE
#ifndef MULTI_CACHE
#define dmac_map_area			__glue(_CACHE,_dma_map_area)
#define dmac_unmap_area 		__glue(_CACHE,_dma_unmap_area)

/*
/*
 * These are private to the dma-mapping API.  Do not use directly.
 * These are private to the dma-mapping API.  Do not use directly.
 * Their sole purpose is to ensure that data held in the cache
 * Their sole purpose is to ensure that data held in the cache