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

Commit 99d1717d authored by Jon Medhurst's avatar Jon Medhurst
Browse files

ARM: Add init_consistent_dma_size()



This function can be called during boot to increase the size of the consistent
DMA region above it's default value of 2MB. It must be called before the memory
allocator is initialised, i.e. before any core_initcall.

Signed-off-by: default avatarJon Medhurst <tixy@yxit.co.uk>
Acked-by: default avatarNicolas Pitre <nicolas.pitre@linaro.org>
parent 93ee7a93
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -205,6 +205,13 @@ extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *,
int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
		void *, dma_addr_t, size_t);
		void *, dma_addr_t, size_t);


/*
 * This can be called during boot to increase the size of the consistent
 * DMA region above it's default value of 2MB. It must be called before the
 * memory allocator is initialised, i.e. before any core_initcall.
 */
extern void __init init_consistent_dma_size(unsigned long size);



#ifdef CONFIG_DMABOUNCE
#ifdef CONFIG_DMABOUNCE
/*
/*
+0 −9
Original line number Original line Diff line number Diff line
@@ -77,16 +77,7 @@
 */
 */
#define IOREMAP_MAX_ORDER	24
#define IOREMAP_MAX_ORDER	24


/*
 * Size of DMA-consistent memory region.  Must be multiple of 2M,
 * between 2MB and 14MB inclusive.
 */
#ifndef CONSISTENT_DMA_SIZE
#define CONSISTENT_DMA_SIZE 	SZ_2M
#endif

#define CONSISTENT_END		(0xffe00000UL)
#define CONSISTENT_END		(0xffe00000UL)
#define CONSISTENT_BASE		(CONSISTENT_END - CONSISTENT_DMA_SIZE)


#else /* CONFIG_MMU */
#else /* CONFIG_MMU */


+38 −11
Original line number Original line Diff line number Diff line
@@ -18,12 +18,14 @@
#include <linux/device.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
#include <linux/highmem.h>
#include <linux/highmem.h>
#include <linux/slab.h>


#include <asm/memory.h>
#include <asm/memory.h>
#include <asm/highmem.h>
#include <asm/highmem.h>
#include <asm/cacheflush.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/tlbflush.h>
#include <asm/sizes.h>
#include <asm/sizes.h>
#include <asm/mach/arch.h>


#include "mm.h"
#include "mm.h"


@@ -117,26 +119,41 @@ static void __dma_free_buffer(struct page *page, size_t size)
}
}


#ifdef CONFIG_MMU
#ifdef CONFIG_MMU
/* Sanity check size */
#if (CONSISTENT_DMA_SIZE % SZ_2M)
#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
#endif


#define CONSISTENT_OFFSET(x)	(((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)

#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
#define CONSISTENT_OFFSET(x)	(((unsigned long)(x) - consistent_base) >> PAGE_SHIFT)
#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PGDIR_SHIFT)


/*
/*
 * These are the page tables (2MB each) covering uncached, DMA consistent allocations
 * These are the page tables (2MB each) covering uncached, DMA consistent allocations
 */
 */
static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
static pte_t **consistent_pte;

#ifdef CONSISTENT_DMA_SIZE
#define DEFAULT_CONSISTENT_DMA_SIZE CONSISTENT_DMA_SIZE
#else
#define DEFAULT_CONSISTENT_DMA_SIZE SZ_2M
#endif

unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE;

void __init init_consistent_dma_size(unsigned long size)
{
	unsigned long base = CONSISTENT_END - ALIGN(size, SZ_2M);

	BUG_ON(consistent_pte); /* Check we're called before DMA region init */
	BUG_ON(base < VMALLOC_END);

	/* Grow region to accommodate specified size  */
	if (base < consistent_base)
		consistent_base = base;
}


#include "vmregion.h"
#include "vmregion.h"


static struct arm_vmregion_head consistent_head = {
static struct arm_vmregion_head consistent_head = {
	.vm_lock	= __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
	.vm_lock	= __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
	.vm_list	= LIST_HEAD_INIT(consistent_head.vm_list),
	.vm_list	= LIST_HEAD_INIT(consistent_head.vm_list),
	.vm_start	= CONSISTENT_BASE,
	.vm_end		= CONSISTENT_END,
	.vm_end		= CONSISTENT_END,
};
};


@@ -155,7 +172,17 @@ static int __init consistent_init(void)
	pmd_t *pmd;
	pmd_t *pmd;
	pte_t *pte;
	pte_t *pte;
	int i = 0;
	int i = 0;
	u32 base = CONSISTENT_BASE;
	unsigned long base = consistent_base;
	unsigned long num_ptes = (CONSISTENT_END - base) >> PGDIR_SHIFT;

	consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
	if (!consistent_pte) {
		pr_err("%s: no memory\n", __func__);
		return -ENOMEM;
	}

	pr_debug("DMA memory: 0x%08lx - 0x%08lx:\n", base, CONSISTENT_END);
	consistent_head.vm_start = base;


	do {
	do {
		pgd = pgd_offset(&init_mm, base);
		pgd = pgd_offset(&init_mm, base);
@@ -198,7 +225,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
	size_t align;
	size_t align;
	int bit;
	int bit;


	if (!consistent_pte[0]) {
	if (!consistent_pte) {
		printk(KERN_ERR "%s: not initialised\n", __func__);
		printk(KERN_ERR "%s: not initialised\n", __func__);
		dump_stack();
		dump_stack();
		return NULL;
		return NULL;
+0 −9
Original line number Original line Diff line number Diff line
@@ -653,9 +653,6 @@ void __init mem_init(void)
			"    ITCM    : 0x%08lx - 0x%08lx   (%4ld kB)\n"
			"    ITCM    : 0x%08lx - 0x%08lx   (%4ld kB)\n"
#endif
#endif
			"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
			"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
#ifdef CONFIG_MMU
			"    DMA     : 0x%08lx - 0x%08lx   (%4ld MB)\n"
#endif
			"    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
			"    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
			"    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB)\n"
			"    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB)\n"
#ifdef CONFIG_HIGHMEM
#ifdef CONFIG_HIGHMEM
@@ -674,9 +671,6 @@ void __init mem_init(void)
			MLK(ITCM_OFFSET, (unsigned long) itcm_end),
			MLK(ITCM_OFFSET, (unsigned long) itcm_end),
#endif
#endif
			MLK(FIXADDR_START, FIXADDR_TOP),
			MLK(FIXADDR_START, FIXADDR_TOP),
#ifdef CONFIG_MMU
			MLM(CONSISTENT_BASE, CONSISTENT_END),
#endif
			MLM(VMALLOC_START, VMALLOC_END),
			MLM(VMALLOC_START, VMALLOC_END),
			MLM(PAGE_OFFSET, (unsigned long)high_memory),
			MLM(PAGE_OFFSET, (unsigned long)high_memory),
#ifdef CONFIG_HIGHMEM
#ifdef CONFIG_HIGHMEM
@@ -699,9 +693,6 @@ void __init mem_init(void)
	 * be detected at build time already.
	 * be detected at build time already.
	 */
	 */
#ifdef CONFIG_MMU
#ifdef CONFIG_MMU
	BUILD_BUG_ON(VMALLOC_END			> CONSISTENT_BASE);
	BUG_ON(VMALLOC_END				> CONSISTENT_BASE);

	BUILD_BUG_ON(TASK_SIZE				> MODULES_VADDR);
	BUILD_BUG_ON(TASK_SIZE				> MODULES_VADDR);
	BUG_ON(TASK_SIZE 				> MODULES_VADDR);
	BUG_ON(TASK_SIZE 				> MODULES_VADDR);
#endif
#endif