mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 06:03:36 -04:00
dma-mapping: add support for dma-coherent-hint-cached
When clients configure their device as dma-coherent-hint-cached this will result in the memory framework only trying to DMA map buffers as IO-coherent if the framework is confident that the buffers are mapped as cached in the CPU. Clients should configure their device as dma-coherent-hint-cached instead of dma-coherent when they need to DMA map both buffers that have cached CPU mappings and other buffers which have uncached CPU mappings. By using dma-coherent-hint-cached the framework will ensure that the client's buffers with uncached CPU mappings don't get DMA mapped as IO-coherent. Change-Id: I990184b54d4148bf952cc672ec267b51efd81473 Signed-off-by: Liam Mark <lmark@codeaurora.org>
This commit is contained in:
parent
333b4ccb21
commit
707e9d34cf
10 changed files with 141 additions and 19 deletions
|
|
@ -77,6 +77,16 @@ config DMA_DIRECT_REMAP
|
|||
bool
|
||||
select DMA_REMAP
|
||||
|
||||
config DMA_COHERENT_HINT_CACHED
|
||||
bool "DMA coherent hint cached"
|
||||
help
|
||||
Enabling this feature allows client to configure their device so
|
||||
that the memory framework will only try to DMA map buffers to the device
|
||||
as IO-coherent if the framework is confident that the buffers are mapped
|
||||
to the CPU as cached.
|
||||
|
||||
If unsure, say "n".
|
||||
|
||||
config DMA_CMA
|
||||
bool "DMA Contiguous Memory Allocator"
|
||||
depends on HAVE_DMA_CONTIGUOUS && CMA
|
||||
|
|
|
|||
|
|
@ -46,6 +46,18 @@ static int dmam_match(struct device *dev, void *res, void *match_data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool is_dma_coherent(struct device *dev, unsigned long attrs)
|
||||
{
|
||||
if (attrs & DMA_ATTR_FORCE_COHERENT)
|
||||
return true;
|
||||
else if (attrs & DMA_ATTR_FORCE_NON_COHERENT)
|
||||
return false;
|
||||
else if (dev_is_dma_coherent(dev))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* dmam_free_coherent - Managed dma_free_coherent()
|
||||
* @dev: Device to free coherent memory for
|
||||
|
|
@ -116,7 +128,7 @@ int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
|
|||
struct page *page;
|
||||
int ret;
|
||||
|
||||
if (!dev_is_dma_coherent(dev)) {
|
||||
if (!is_dma_coherent(dev, attrs)) {
|
||||
unsigned long pfn;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN))
|
||||
|
|
@ -154,6 +166,9 @@ int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt,
|
|||
{
|
||||
const struct dma_map_ops *ops = get_dma_ops(dev);
|
||||
|
||||
if (dev_is_dma_coherent_hint_cached(dev))
|
||||
attrs |= DMA_ATTR_FORCE_COHERENT;
|
||||
|
||||
if (dma_is_direct(ops))
|
||||
return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr,
|
||||
size, attrs);
|
||||
|
|
@ -164,18 +179,6 @@ int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt,
|
|||
EXPORT_SYMBOL(dma_get_sgtable_attrs);
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
static bool is_dma_coherent(struct device *dev, unsigned long attrs)
|
||||
{
|
||||
if (attrs & DMA_ATTR_FORCE_COHERENT)
|
||||
return true;
|
||||
else if (attrs & DMA_ATTR_FORCE_NON_COHERENT)
|
||||
return false;
|
||||
else if (dev_is_dma_coherent(dev))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the page attributes used for mapping dma_alloc_* memory, either in
|
||||
* kernel space if remapping is needed, or to userspace through dma_mmap_*.
|
||||
|
|
@ -216,7 +219,7 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
|
|||
if (off >= count || user_count > count - off)
|
||||
return -ENXIO;
|
||||
|
||||
if (!dev_is_dma_coherent(dev)) {
|
||||
if (!is_dma_coherent(dev, attrs)) {
|
||||
if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN))
|
||||
return -ENXIO;
|
||||
|
||||
|
|
@ -275,6 +278,9 @@ int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
|
|||
{
|
||||
const struct dma_map_ops *ops = get_dma_ops(dev);
|
||||
|
||||
if (dev_is_dma_coherent_hint_cached(dev))
|
||||
attrs |= DMA_ATTR_FORCE_COHERENT;
|
||||
|
||||
if (dma_is_direct(ops))
|
||||
return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size,
|
||||
attrs);
|
||||
|
|
@ -315,6 +321,9 @@ void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
|
|||
|
||||
WARN_ON(!of_reserved_mem_device_is_init(dev));
|
||||
|
||||
if (dev_is_dma_coherent_hint_cached(dev))
|
||||
attrs |= DMA_ATTR_FORCE_COHERENT;
|
||||
|
||||
if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
|
||||
return cpu_addr;
|
||||
|
||||
|
|
@ -338,6 +347,9 @@ void dma_free_attrs(struct device *dev, size_t size, void *cpu_addr,
|
|||
{
|
||||
const struct dma_map_ops *ops = get_dma_ops(dev);
|
||||
|
||||
if (dev_is_dma_coherent_hint_cached(dev))
|
||||
attrs |= DMA_ATTR_FORCE_COHERENT;
|
||||
|
||||
if (dma_release_from_dev_coherent(dev, get_order(size), cpu_addr))
|
||||
return;
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue