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_DMA_API_DEBUG
|
||||
select HAVE_DMA_ATTRS
|
||||
select HAVE_DMA_CONTIGUOUS
|
||||
select HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
select HAVE_GENERIC_DMA_COHERENT
|
||||
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/slab.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dma-contiguous.h>
|
||||
#include <linux/vmalloc.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) &&
|
||||
dev->coherent_dma_mask <= DMA_BIT_MASK(32))
|
||||
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,
|
||||
|
@ -53,7 +66,15 @@ static void arm64_swiotlb_free_coherent(struct device *dev, size_t size,
|
|||
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 = {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <linux/memblock.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/dma-contiguous.h>
|
||||
|
||||
#include <asm/sections.h>
|
||||
#include <asm/setup.h>
|
||||
|
@ -159,6 +160,8 @@ void __init arm64_memblock_init(void)
|
|||
memblock_reserve(base, size);
|
||||
}
|
||||
|
||||
dma_contiguous_reserve(0);
|
||||
|
||||
memblock_allow_resize();
|
||||
memblock_dump_all();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue