arm64: Enable CMA
arm64 bit targets need the features CMA provides. Add the appropriate hooks, header files, and Kconfig to allow this to happen. Cc: Will Deacon <will.deacon@arm.com> Cc: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Laura Abbott <lauraa@codeaurora.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
c666e8d5ca
commit
6ac2104deb
|
@ -27,6 +27,7 @@ config ARM64
|
||||||
select HAVE_DEBUG_KMEMLEAK
|
select HAVE_DEBUG_KMEMLEAK
|
||||||
select HAVE_DMA_API_DEBUG
|
select HAVE_DMA_API_DEBUG
|
||||||
select HAVE_DMA_ATTRS
|
select HAVE_DMA_ATTRS
|
||||||
|
select HAVE_DMA_CONTIGUOUS
|
||||||
select HAVE_EFFICIENT_UNALIGNED_ACCESS
|
select HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||||
select HAVE_GENERIC_DMA_COHERENT
|
select HAVE_GENERIC_DMA_COHERENT
|
||||||
select HAVE_HW_BREAKPOINT if PERF_EVENTS
|
select HAVE_HW_BREAKPOINT if PERF_EVENTS
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
* only version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ASM_DMA_CONTIGUOUS_H
|
||||||
|
#define _ASM_DMA_CONTIGUOUS_H
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
#ifdef CONFIG_DMA_CMA
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <asm-generic/dma-contiguous.h>
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <linux/dma-contiguous.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/swiotlb.h>
|
#include <linux/swiotlb.h>
|
||||||
|
|
||||||
|
@ -41,7 +42,19 @@ static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size,
|
||||||
if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
|
if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
|
||||||
dev->coherent_dma_mask <= DMA_BIT_MASK(32))
|
dev->coherent_dma_mask <= DMA_BIT_MASK(32))
|
||||||
flags |= GFP_DMA32;
|
flags |= GFP_DMA32;
|
||||||
return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
|
if (IS_ENABLED(CONFIG_DMA_CMA)) {
|
||||||
|
struct page *page;
|
||||||
|
|
||||||
|
page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
|
||||||
|
get_order(size));
|
||||||
|
if (!page)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*dma_handle = phys_to_dma(dev, page_to_phys(page));
|
||||||
|
return page_address(page);
|
||||||
|
} else {
|
||||||
|
return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arm64_swiotlb_free_coherent(struct device *dev, size_t size,
|
static void arm64_swiotlb_free_coherent(struct device *dev, size_t size,
|
||||||
|
@ -53,7 +66,15 @@ static void arm64_swiotlb_free_coherent(struct device *dev, size_t size,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
swiotlb_free_coherent(dev, size, vaddr, dma_handle);
|
if (IS_ENABLED(CONFIG_DMA_CMA)) {
|
||||||
|
phys_addr_t paddr = dma_to_phys(dev, dma_handle);
|
||||||
|
|
||||||
|
dma_release_from_contiguous(dev,
|
||||||
|
phys_to_page(paddr),
|
||||||
|
size >> PAGE_SHIFT);
|
||||||
|
} else {
|
||||||
|
swiotlb_free_coherent(dev, size, vaddr, dma_handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dma_map_ops arm64_swiotlb_dma_ops = {
|
static struct dma_map_ops arm64_swiotlb_dma_ops = {
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
#include <linux/sort.h>
|
#include <linux/sort.h>
|
||||||
#include <linux/of_fdt.h>
|
#include <linux/of_fdt.h>
|
||||||
|
#include <linux/dma-contiguous.h>
|
||||||
|
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
@ -159,6 +160,8 @@ void __init arm64_memblock_init(void)
|
||||||
memblock_reserve(base, size);
|
memblock_reserve(base, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dma_contiguous_reserve(0);
|
||||||
|
|
||||||
memblock_allow_resize();
|
memblock_allow_resize();
|
||||||
memblock_dump_all();
|
memblock_dump_all();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue