Commit 4ce63fcd authored by Marek Szyprowski's avatar Marek Szyprowski

ARM: dma-mapping: add support for IOMMU mapper

This patch add a complete implementation of DMA-mapping API for
devices which have IOMMU support.

This implementation tries to optimize dma address space usage by remapping
all possible physical memory chunks into a single dma address space chunk.

DMA address space is managed on top of the bitmap stored in the
dma_iommu_mapping structure stored in device->archdata. Platform setup
code has to initialize parameters of the dma address space (base address,
size, allocation precision order) with arm_iommu_create_mapping() function.
To reduce the size of the bitmap, all allocations are aligned to the
specified order of base 4 KiB pages.

dma_alloc_* functions allocate physical memory in chunks, each with
alloc_pages() function to avoid failing if the physical memory gets
fragmented. In worst case the allocated buffer is composed of 4 KiB page
chunks.

dma_map_sg() function minimizes the total number of dma address space
chunks by merging of physical memory chunks into one larger dma address
space chunk. If requested chunk (scatter list entry) boundaries
match physical page boundaries, most calls to dma_map_sg() requests will
result in creating only one chunk in dma address space.

dma_map_page() simply creates a mapping for the given page(s) in the dma
address space.

All dma functions also perform required cache operation like their
counterparts from the arm linear physical memory mapping version.

This patch contains code and fixes kindly provided by:
- Krishna Reddy <vdumpa@nvidia.com>,
- Andrzej Pietrasiewicz <andrzej.p@samsung.com>,
- Hiroshi DOYU <hdoyu@nvidia.com>
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Acked-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tested-By: default avatarSubash Patel <subash.ramaswamy@linaro.org>
parent f99d6034
...@@ -46,6 +46,14 @@ config ARM ...@@ -46,6 +46,14 @@ config ARM
config ARM_HAS_SG_CHAIN config ARM_HAS_SG_CHAIN
bool bool
config NEED_SG_DMA_LENGTH
bool
config ARM_DMA_USE_IOMMU
select NEED_SG_DMA_LENGTH
select ARM_HAS_SG_CHAIN
bool
config HAVE_PWM config HAVE_PWM
bool bool
......
...@@ -14,6 +14,9 @@ struct dev_archdata { ...@@ -14,6 +14,9 @@ struct dev_archdata {
#ifdef CONFIG_IOMMU_API #ifdef CONFIG_IOMMU_API
void *iommu; /* private IOMMU data */ void *iommu; /* private IOMMU data */
#endif #endif
#ifdef CONFIG_ARM_DMA_USE_IOMMU
struct dma_iommu_mapping *mapping;
#endif
}; };
struct omap_device; struct omap_device;
......
#ifndef ASMARM_DMA_IOMMU_H
#define ASMARM_DMA_IOMMU_H
#ifdef __KERNEL__
#include <linux/mm_types.h>
#include <linux/scatterlist.h>
#include <linux/dma-debug.h>
#include <linux/kmemcheck.h>
struct dma_iommu_mapping {
/* iommu specific data */
struct iommu_domain *domain;
void *bitmap;
size_t bits;
unsigned int order;
dma_addr_t base;
spinlock_t lock;
struct kref kref;
};
struct dma_iommu_mapping *
arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
int order);
void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping);
int arm_iommu_attach_device(struct device *dev,
struct dma_iommu_mapping *mapping);
#endif /* __KERNEL__ */
#endif
This diff is collapsed.
...@@ -17,7 +17,7 @@ struct arm_vmregion { ...@@ -17,7 +17,7 @@ struct arm_vmregion {
struct list_head vm_list; struct list_head vm_list;
unsigned long vm_start; unsigned long vm_start;
unsigned long vm_end; unsigned long vm_end;
struct page *vm_pages; void *priv;
int vm_active; int vm_active;
const void *caller; const void *caller;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment