18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> 38c2ecf20Sopenharmony_ci * Copyright (C) 2009 Wind River Systems Inc 48c2ecf20Sopenharmony_ci * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Based on DMA code from MIPS. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 98c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 108c2ecf20Sopenharmony_ci * for more details. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/types.h> 148c2ecf20Sopenharmony_ci#include <linux/mm.h> 158c2ecf20Sopenharmony_ci#include <linux/string.h> 168c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 178c2ecf20Sopenharmony_ci#include <linux/io.h> 188c2ecf20Sopenharmony_ci#include <linux/cache.h> 198c2ecf20Sopenharmony_ci#include <asm/cacheflush.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_civoid arch_sync_dma_for_device(phys_addr_t paddr, size_t size, 228c2ecf20Sopenharmony_ci enum dma_data_direction dir) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci void *vaddr = phys_to_virt(paddr); 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci switch (dir) { 278c2ecf20Sopenharmony_ci case DMA_FROM_DEVICE: 288c2ecf20Sopenharmony_ci invalidate_dcache_range((unsigned long)vaddr, 298c2ecf20Sopenharmony_ci (unsigned long)(vaddr + size)); 308c2ecf20Sopenharmony_ci break; 318c2ecf20Sopenharmony_ci case DMA_TO_DEVICE: 328c2ecf20Sopenharmony_ci /* 338c2ecf20Sopenharmony_ci * We just need to flush the caches here , but Nios2 flush 348c2ecf20Sopenharmony_ci * instruction will do both writeback and invalidate. 358c2ecf20Sopenharmony_ci */ 368c2ecf20Sopenharmony_ci case DMA_BIDIRECTIONAL: /* flush and invalidate */ 378c2ecf20Sopenharmony_ci flush_dcache_range((unsigned long)vaddr, 388c2ecf20Sopenharmony_ci (unsigned long)(vaddr + size)); 398c2ecf20Sopenharmony_ci break; 408c2ecf20Sopenharmony_ci default: 418c2ecf20Sopenharmony_ci BUG(); 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_civoid arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, 468c2ecf20Sopenharmony_ci enum dma_data_direction dir) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci void *vaddr = phys_to_virt(paddr); 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci switch (dir) { 518c2ecf20Sopenharmony_ci case DMA_BIDIRECTIONAL: 528c2ecf20Sopenharmony_ci case DMA_FROM_DEVICE: 538c2ecf20Sopenharmony_ci invalidate_dcache_range((unsigned long)vaddr, 548c2ecf20Sopenharmony_ci (unsigned long)(vaddr + size)); 558c2ecf20Sopenharmony_ci break; 568c2ecf20Sopenharmony_ci case DMA_TO_DEVICE: 578c2ecf20Sopenharmony_ci break; 588c2ecf20Sopenharmony_ci default: 598c2ecf20Sopenharmony_ci BUG(); 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_civoid arch_dma_prep_coherent(struct page *page, size_t size) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci unsigned long start = (unsigned long)page_address(page); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci flush_dcache_range(start, start + size); 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_civoid *arch_dma_set_uncached(void *ptr, size_t size) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci unsigned long addr = (unsigned long)ptr; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci addr |= CONFIG_NIOS2_IO_REGION_BASE; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci return (void *)ptr; 778c2ecf20Sopenharmony_ci} 78