You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
4.5 KiB
164 lines
4.5 KiB
#ifndef __LINUX_CMA_H |
|
#define __LINUX_CMA_H |
|
|
|
/* |
|
* Contiguous Memory Allocator for DMA mapping framework |
|
* Copyright (c) 2010-2011 by Samsung Electronics. |
|
* Written by: |
|
* Marek Szyprowski <m.szyprowski@samsung.com> |
|
* Michal Nazarewicz <mina86@mina86.com> |
|
* |
|
* This program is free software; you can redistribute it and/or |
|
* modify it under the terms of the GNU General Public License as |
|
* published by the Free Software Foundation; either version 2 of the |
|
* License or (at your optional) any later version of the license. |
|
*/ |
|
|
|
/* |
|
* Contiguous Memory Allocator |
|
* |
|
* The Contiguous Memory Allocator (CMA) makes it possible to |
|
* allocate big contiguous chunks of memory after the system has |
|
* booted. |
|
* |
|
* Why is it needed? |
|
* |
|
* Various devices on embedded systems have no scatter-getter and/or |
|
* IO map support and require contiguous blocks of memory to |
|
* operate. They include devices such as cameras, hardware video |
|
* coders, etc. |
|
* |
|
* Such devices often require big memory buffers (a full HD frame |
|
* is, for instance, more then 2 mega pixels large, i.e. more than 6 |
|
* MB of memory), which makes mechanisms such as kmalloc() or |
|
* alloc_page() ineffective. |
|
* |
|
* At the same time, a solution where a big memory region is |
|
* reserved for a device is suboptimal since often more memory is |
|
* reserved then strictly required and, moreover, the memory is |
|
* inaccessible to page system even if device drivers don't use it. |
|
* |
|
* CMA tries to solve this issue by operating on memory regions |
|
* where only movable pages can be allocated from. This way, kernel |
|
* can use the memory for pagecache and when device driver requests |
|
* it, allocated pages can be migrated. |
|
* |
|
* Driver usage |
|
* |
|
* CMA should not be used by the device drivers directly. It is |
|
* only a helper framework for dma-mapping subsystem. |
|
* |
|
* For more information, see kernel-docs in drivers/base/dma-contiguous.c |
|
*/ |
|
|
|
#ifdef __KERNEL__ |
|
|
|
#include <linux/device.h> |
|
|
|
struct cma; |
|
struct page; |
|
|
|
#ifdef CONFIG_DMA_CMA |
|
|
|
extern struct cma *dma_contiguous_default_area; |
|
|
|
static inline struct cma *dev_get_cma_area(struct device *dev) |
|
{ |
|
if (dev && dev->cma_area) |
|
return dev->cma_area; |
|
return dma_contiguous_default_area; |
|
} |
|
|
|
static inline void dev_set_cma_area(struct device *dev, struct cma *cma) |
|
{ |
|
if (dev) |
|
dev->cma_area = cma; |
|
} |
|
|
|
static inline void dma_contiguous_set_default(struct cma *cma) |
|
{ |
|
dma_contiguous_default_area = cma; |
|
} |
|
|
|
void dma_contiguous_reserve(phys_addr_t addr_limit); |
|
|
|
int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, |
|
phys_addr_t limit, struct cma **res_cma, |
|
bool fixed); |
|
|
|
/** |
|
* dma_declare_contiguous() - reserve area for contiguous memory handling |
|
* for particular device |
|
* @dev: Pointer to device structure. |
|
* @size: Size of the reserved memory. |
|
* @base: Start address of the reserved memory (optional, 0 for any). |
|
* @limit: End address of the reserved memory (optional, 0 for any). |
|
* |
|
* This function reserves memory for specified device. It should be |
|
* called by board specific code when early allocator (memblock or bootmem) |
|
* is still activate. |
|
*/ |
|
|
|
static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size, |
|
phys_addr_t base, phys_addr_t limit) |
|
{ |
|
struct cma *cma; |
|
int ret; |
|
ret = dma_contiguous_reserve_area(size, base, limit, &cma, true); |
|
if (ret == 0) |
|
dev_set_cma_area(dev, cma); |
|
|
|
return ret; |
|
} |
|
|
|
struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, |
|
unsigned int order); |
|
bool dma_release_from_contiguous(struct device *dev, struct page *pages, |
|
int count); |
|
|
|
#else |
|
|
|
static inline struct cma *dev_get_cma_area(struct device *dev) |
|
{ |
|
return NULL; |
|
} |
|
|
|
static inline void dev_set_cma_area(struct device *dev, struct cma *cma) { } |
|
|
|
static inline void dma_contiguous_set_default(struct cma *cma) { } |
|
|
|
static inline void dma_contiguous_reserve(phys_addr_t limit) { } |
|
|
|
static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, |
|
phys_addr_t limit, struct cma **res_cma, |
|
bool fixed) |
|
{ |
|
return -ENOSYS; |
|
} |
|
|
|
static inline |
|
int dma_declare_contiguous(struct device *dev, phys_addr_t size, |
|
phys_addr_t base, phys_addr_t limit) |
|
{ |
|
return -ENOSYS; |
|
} |
|
|
|
static inline |
|
struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, |
|
unsigned int order) |
|
{ |
|
return NULL; |
|
} |
|
|
|
static inline |
|
bool dma_release_from_contiguous(struct device *dev, struct page *pages, |
|
int count) |
|
{ |
|
return false; |
|
} |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
#endif
|
|
|