11162b070SVineet Gupta /* 21162b070SVineet Gupta * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 31162b070SVineet Gupta * 41162b070SVineet Gupta * This program is free software; you can redistribute it and/or modify 51162b070SVineet Gupta * it under the terms of the GNU General Public License version 2 as 61162b070SVineet Gupta * published by the Free Software Foundation. 71162b070SVineet Gupta */ 81162b070SVineet Gupta 91162b070SVineet Gupta /* 101162b070SVineet Gupta * DMA Coherent API Notes 111162b070SVineet Gupta * 121162b070SVineet Gupta * I/O is inherently non-coherent on ARC. So a coherent DMA buffer is 131162b070SVineet Gupta * implemented by accessintg it using a kernel virtual address, with 141162b070SVineet Gupta * Cache bit off in the TLB entry. 151162b070SVineet Gupta * 161162b070SVineet Gupta * The default DMA address == Phy address which is 0x8000_0000 based. 171162b070SVineet Gupta * A platform/device can make it zero based, by over-riding 181162b070SVineet Gupta * plat_{dma,kernel}_addr_to_{kernel,dma} 191162b070SVineet Gupta */ 201162b070SVineet Gupta 211162b070SVineet Gupta #include <linux/dma-mapping.h> 221162b070SVineet Gupta #include <linux/dma-debug.h> 231162b070SVineet Gupta #include <linux/export.h> 241162b070SVineet Gupta #include <asm/cacheflush.h> 251162b070SVineet Gupta 261162b070SVineet Gupta /* 271162b070SVineet Gupta * Helpers for Coherent DMA API. 281162b070SVineet Gupta */ 291162b070SVineet Gupta void *dma_alloc_noncoherent(struct device *dev, size_t size, 301162b070SVineet Gupta dma_addr_t *dma_handle, gfp_t gfp) 311162b070SVineet Gupta { 321162b070SVineet Gupta void *paddr; 331162b070SVineet Gupta 341162b070SVineet Gupta /* This is linear addr (0x8000_0000 based) */ 351162b070SVineet Gupta paddr = alloc_pages_exact(size, gfp); 361162b070SVineet Gupta if (!paddr) 371162b070SVineet Gupta return NULL; 381162b070SVineet Gupta 391162b070SVineet Gupta /* This is bus address, platform dependent */ 401162b070SVineet Gupta *dma_handle = plat_kernel_addr_to_dma(dev, paddr); 411162b070SVineet Gupta 421162b070SVineet Gupta return paddr; 431162b070SVineet Gupta } 441162b070SVineet Gupta EXPORT_SYMBOL(dma_alloc_noncoherent); 451162b070SVineet Gupta 461162b070SVineet Gupta void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, 471162b070SVineet Gupta dma_addr_t dma_handle) 481162b070SVineet Gupta { 491162b070SVineet Gupta free_pages_exact((void *)plat_dma_addr_to_kernel(dev, dma_handle), 501162b070SVineet Gupta size); 511162b070SVineet Gupta } 521162b070SVineet Gupta EXPORT_SYMBOL(dma_free_noncoherent); 531162b070SVineet Gupta 541162b070SVineet Gupta void *dma_alloc_coherent(struct device *dev, size_t size, 551162b070SVineet Gupta dma_addr_t *dma_handle, gfp_t gfp) 561162b070SVineet Gupta { 571162b070SVineet Gupta void *paddr, *kvaddr; 581162b070SVineet Gupta 591162b070SVineet Gupta /* This is linear addr (0x8000_0000 based) */ 601162b070SVineet Gupta paddr = alloc_pages_exact(size, gfp); 611162b070SVineet Gupta if (!paddr) 621162b070SVineet Gupta return NULL; 631162b070SVineet Gupta 641162b070SVineet Gupta /* This is kernel Virtual address (0x7000_0000 based) */ 651162b070SVineet Gupta kvaddr = ioremap_nocache((unsigned long)paddr, size); 661162b070SVineet Gupta if (kvaddr != NULL) 671162b070SVineet Gupta memset(kvaddr, 0, size); 681162b070SVineet Gupta 691162b070SVineet Gupta /* This is bus address, platform dependent */ 701162b070SVineet Gupta *dma_handle = plat_kernel_addr_to_dma(dev, paddr); 711162b070SVineet Gupta 721162b070SVineet Gupta return kvaddr; 731162b070SVineet Gupta } 741162b070SVineet Gupta EXPORT_SYMBOL(dma_alloc_coherent); 751162b070SVineet Gupta 761162b070SVineet Gupta void dma_free_coherent(struct device *dev, size_t size, void *kvaddr, 771162b070SVineet Gupta dma_addr_t dma_handle) 781162b070SVineet Gupta { 791162b070SVineet Gupta iounmap((void __force __iomem *)kvaddr); 801162b070SVineet Gupta 811162b070SVineet Gupta free_pages_exact((void *)plat_dma_addr_to_kernel(dev, dma_handle), 821162b070SVineet Gupta size); 831162b070SVineet Gupta } 841162b070SVineet Gupta EXPORT_SYMBOL(dma_free_coherent); 851162b070SVineet Gupta 861162b070SVineet Gupta /* 871162b070SVineet Gupta * Helper for streaming DMA... 881162b070SVineet Gupta */ 891162b070SVineet Gupta void __arc_dma_cache_sync(unsigned long paddr, size_t size, 901162b070SVineet Gupta enum dma_data_direction dir) 911162b070SVineet Gupta { 921162b070SVineet Gupta __inline_dma_cache_sync(paddr, size, dir); 931162b070SVineet Gupta } 941162b070SVineet Gupta EXPORT_SYMBOL(__arc_dma_cache_sync); 95