aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/mm/dma-mapping.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/mm/dma-mapping.c')
-rw-r--r--arch/arm64/mm/dma-mapping.c195
1 files changed, 145 insertions, 50 deletions
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 4164c5ace9f8..d92094203913 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -20,13 +20,11 @@
20#include <linux/gfp.h> 20#include <linux/gfp.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/genalloc.h>
23#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
24#include <linux/dma-contiguous.h> 25#include <linux/dma-contiguous.h>
25#include <linux/of.h>
26#include <linux/platform_device.h>
27#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
28#include <linux/swiotlb.h> 27#include <linux/swiotlb.h>
29#include <linux/amba/bus.h>
30 28
31#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
32 30
@@ -41,6 +39,54 @@ static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
41 return prot; 39 return prot;
42} 40}
43 41
42static struct gen_pool *atomic_pool;
43
44#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
45static size_t atomic_pool_size = DEFAULT_DMA_COHERENT_POOL_SIZE;
46
47static int __init early_coherent_pool(char *p)
48{
49 atomic_pool_size = memparse(p, &p);
50 return 0;
51}
52early_param("coherent_pool", early_coherent_pool);
53
54static void *__alloc_from_pool(size_t size, struct page **ret_page)
55{
56 unsigned long val;
57 void *ptr = NULL;
58
59 if (!atomic_pool) {
60 WARN(1, "coherent pool not initialised!\n");
61 return NULL;
62 }
63
64 val = gen_pool_alloc(atomic_pool, size);
65 if (val) {
66 phys_addr_t phys = gen_pool_virt_to_phys(atomic_pool, val);
67
68 *ret_page = phys_to_page(phys);
69 ptr = (void *)val;
70 }
71
72 return ptr;
73}
74
75static bool __in_atomic_pool(void *start, size_t size)
76{
77 return addr_in_gen_pool(atomic_pool, (unsigned long)start, size);
78}
79
80static int __free_from_pool(void *start, size_t size)
81{
82 if (!__in_atomic_pool(start, size))
83 return 0;
84
85 gen_pool_free(atomic_pool, (unsigned long)start, size);
86
87 return 1;
88}
89
44static void *__dma_alloc_coherent(struct device *dev, size_t size, 90static void *__dma_alloc_coherent(struct device *dev, size_t size,
45 dma_addr_t *dma_handle, gfp_t flags, 91 dma_addr_t *dma_handle, gfp_t flags,
46 struct dma_attrs *attrs) 92 struct dma_attrs *attrs)
@@ -53,7 +99,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
53 if (IS_ENABLED(CONFIG_ZONE_DMA) && 99 if (IS_ENABLED(CONFIG_ZONE_DMA) &&
54 dev->coherent_dma_mask <= DMA_BIT_MASK(32)) 100 dev->coherent_dma_mask <= DMA_BIT_MASK(32))
55 flags |= GFP_DMA; 101 flags |= GFP_DMA;
56 if (IS_ENABLED(CONFIG_DMA_CMA)) { 102 if (IS_ENABLED(CONFIG_DMA_CMA) && (flags & __GFP_WAIT)) {
57 struct page *page; 103 struct page *page;
58 104
59 size = PAGE_ALIGN(size); 105 size = PAGE_ALIGN(size);
@@ -73,50 +119,54 @@ static void __dma_free_coherent(struct device *dev, size_t size,
73 void *vaddr, dma_addr_t dma_handle, 119 void *vaddr, dma_addr_t dma_handle,
74 struct dma_attrs *attrs) 120 struct dma_attrs *attrs)
75{ 121{
122 bool freed;
123 phys_addr_t paddr = dma_to_phys(dev, dma_handle);
124
76 if (dev == NULL) { 125 if (dev == NULL) {
77 WARN_ONCE(1, "Use an actual device structure for DMA allocation\n"); 126 WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
78 return; 127 return;
79 } 128 }
80 129
81 if (IS_ENABLED(CONFIG_DMA_CMA)) { 130 freed = dma_release_from_contiguous(dev,
82 phys_addr_t paddr = dma_to_phys(dev, dma_handle);
83
84 dma_release_from_contiguous(dev,
85 phys_to_page(paddr), 131 phys_to_page(paddr),
86 size >> PAGE_SHIFT); 132 size >> PAGE_SHIFT);
87 } else { 133 if (!freed)
88 swiotlb_free_coherent(dev, size, vaddr, dma_handle); 134 swiotlb_free_coherent(dev, size, vaddr, dma_handle);
89 }
90} 135}
91 136
92static void *__dma_alloc_noncoherent(struct device *dev, size_t size, 137static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
93 dma_addr_t *dma_handle, gfp_t flags, 138 dma_addr_t *dma_handle, gfp_t flags,
94 struct dma_attrs *attrs) 139 struct dma_attrs *attrs)
95{ 140{
96 struct page *page, **map; 141 struct page *page;
97 void *ptr, *coherent_ptr; 142 void *ptr, *coherent_ptr;
98 int order, i;
99 143
100 size = PAGE_ALIGN(size); 144 size = PAGE_ALIGN(size);
101 order = get_order(size); 145
146 if (!(flags & __GFP_WAIT)) {
147 struct page *page = NULL;
148 void *addr = __alloc_from_pool(size, &page);
149
150 if (addr)
151 *dma_handle = phys_to_dma(dev, page_to_phys(page));
152
153 return addr;
154
155 }
102 156
103 ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs); 157 ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs);
104 if (!ptr) 158 if (!ptr)
105 goto no_mem; 159 goto no_mem;
106 map = kmalloc(sizeof(struct page *) << order, flags & ~GFP_DMA);
107 if (!map)
108 goto no_map;
109 160
110 /* remove any dirty cache lines on the kernel alias */ 161 /* remove any dirty cache lines on the kernel alias */
111 __dma_flush_range(ptr, ptr + size); 162 __dma_flush_range(ptr, ptr + size);
112 163
113 /* create a coherent mapping */ 164 /* create a coherent mapping */
114 page = virt_to_page(ptr); 165 page = virt_to_page(ptr);
115 for (i = 0; i < (size >> PAGE_SHIFT); i++) 166 coherent_ptr = dma_common_contiguous_remap(page, size, VM_USERMAP,
116 map[i] = page + i; 167 __get_dma_pgprot(attrs,
117 coherent_ptr = vmap(map, size >> PAGE_SHIFT, VM_MAP, 168 __pgprot(PROT_NORMAL_NC), false),
118 __get_dma_pgprot(attrs, __pgprot(PROT_NORMAL_NC), false)); 169 NULL);
119 kfree(map);
120 if (!coherent_ptr) 170 if (!coherent_ptr)
121 goto no_map; 171 goto no_map;
122 172
@@ -125,7 +175,7 @@ static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
125no_map: 175no_map:
126 __dma_free_coherent(dev, size, ptr, *dma_handle, attrs); 176 __dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
127no_mem: 177no_mem:
128 *dma_handle = ~0; 178 *dma_handle = DMA_ERROR_CODE;
129 return NULL; 179 return NULL;
130} 180}
131 181
@@ -135,6 +185,8 @@ static void __dma_free_noncoherent(struct device *dev, size_t size,
135{ 185{
136 void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle)); 186 void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
137 187
188 if (__free_from_pool(vaddr, size))
189 return;
138 vunmap(vaddr); 190 vunmap(vaddr);
139 __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs); 191 __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
140} 192}
@@ -308,45 +360,88 @@ struct dma_map_ops coherent_swiotlb_dma_ops = {
308}; 360};
309EXPORT_SYMBOL(coherent_swiotlb_dma_ops); 361EXPORT_SYMBOL(coherent_swiotlb_dma_ops);
310 362
311static int dma_bus_notifier(struct notifier_block *nb, 363extern int swiotlb_late_init_with_default_size(size_t default_size);
312 unsigned long event, void *_dev)
313{
314 struct device *dev = _dev;
315
316 if (event != BUS_NOTIFY_ADD_DEVICE)
317 return NOTIFY_DONE;
318
319 if (of_property_read_bool(dev->of_node, "dma-coherent"))
320 set_dma_ops(dev, &coherent_swiotlb_dma_ops);
321 364
322 return NOTIFY_OK; 365static int __init atomic_pool_init(void)
366{
367 pgprot_t prot = __pgprot(PROT_NORMAL_NC);
368 unsigned long nr_pages = atomic_pool_size >> PAGE_SHIFT;
369 struct page *page;
370 void *addr;
371 unsigned int pool_size_order = get_order(atomic_pool_size);
372
373 if (dev_get_cma_area(NULL))
374 page = dma_alloc_from_contiguous(NULL, nr_pages,
375 pool_size_order);
376 else
377 page = alloc_pages(GFP_DMA, pool_size_order);
378
379 if (page) {
380 int ret;
381 void *page_addr = page_address(page);
382
383 memset(page_addr, 0, atomic_pool_size);
384 __dma_flush_range(page_addr, page_addr + atomic_pool_size);
385
386 atomic_pool = gen_pool_create(PAGE_SHIFT, -1);
387 if (!atomic_pool)
388 goto free_page;
389
390 addr = dma_common_contiguous_remap(page, atomic_pool_size,
391 VM_USERMAP, prot, atomic_pool_init);
392
393 if (!addr)
394 goto destroy_genpool;
395
396 ret = gen_pool_add_virt(atomic_pool, (unsigned long)addr,
397 page_to_phys(page),
398 atomic_pool_size, -1);
399 if (ret)
400 goto remove_mapping;
401
402 gen_pool_set_algo(atomic_pool,
403 gen_pool_first_fit_order_align,
404 (void *)PAGE_SHIFT);
405
406 pr_info("DMA: preallocated %zu KiB pool for atomic allocations\n",
407 atomic_pool_size / 1024);
408 return 0;
409 }
410 goto out;
411
412remove_mapping:
413 dma_common_free_remap(addr, atomic_pool_size, VM_USERMAP);
414destroy_genpool:
415 gen_pool_destroy(atomic_pool);
416 atomic_pool = NULL;
417free_page:
418 if (!dma_release_from_contiguous(NULL, page, nr_pages))
419 __free_pages(page, pool_size_order);
420out:
421 pr_err("DMA: failed to allocate %zu KiB pool for atomic coherent allocation\n",
422 atomic_pool_size / 1024);
423 return -ENOMEM;
323} 424}
324 425
325static struct notifier_block platform_bus_nb = {
326 .notifier_call = dma_bus_notifier,
327};
328
329static struct notifier_block amba_bus_nb = {
330 .notifier_call = dma_bus_notifier,
331};
332
333extern int swiotlb_late_init_with_default_size(size_t default_size);
334
335static int __init swiotlb_late_init(void) 426static int __init swiotlb_late_init(void)
336{ 427{
337 size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT); 428 size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT);
338 429
339 /*
340 * These must be registered before of_platform_populate().
341 */
342 bus_register_notifier(&platform_bus_type, &platform_bus_nb);
343 bus_register_notifier(&amba_bustype, &amba_bus_nb);
344
345 dma_ops = &noncoherent_swiotlb_dma_ops; 430 dma_ops = &noncoherent_swiotlb_dma_ops;
346 431
347 return swiotlb_late_init_with_default_size(swiotlb_size); 432 return swiotlb_late_init_with_default_size(swiotlb_size);
348} 433}
349arch_initcall(swiotlb_late_init); 434
435static int __init arm64_dma_init(void)
436{
437 int ret = 0;
438
439 ret |= swiotlb_late_init();
440 ret |= atomic_pool_init();
441
442 return ret;
443}
444arch_initcall(arm64_dma_init);
350 445
351#define PREALLOC_DMA_DEBUG_ENTRIES 4096 446#define PREALLOC_DMA_DEBUG_ENTRIES 4096
352 447