1 // SPDX-License-Identifier: GPL-2.0-or-later << 2 /* 1 /* 3 * OpenRISC Linux !! 2 * This file is subject to the terms and conditions of the GNU General Public 4 * !! 3 * License. See the file COPYING in the main directory of this archive 5 * Linux architectural port borrowing liberall !! 4 * for more details. 6 * others. All original copyrights apply as p << 7 * declaration. << 8 * << 9 * Modifications for the OpenRISC architecture << 10 * Copyright (C) 2003 Matjaz Breskvar <phoenix << 11 * Copyright (C) 2010-2011 Jonas Bonn <jonas@s << 12 * << 13 * DMA mapping callbacks... << 14 */ 5 */ 15 6 16 #include <linux/dma-map-ops.h> 7 #include <linux/dma-map-ops.h> 17 #include <linux/pagewalk.h> !! 8 #include <linux/kernel.h> >> 9 #include <asm/cacheflush.h> 18 10 19 #include <asm/cpuinfo.h> !! 11 #ifndef CONFIG_COLDFIRE 20 #include <asm/spr_defs.h> !! 12 void arch_dma_prep_coherent(struct page *page, size_t size) 21 #include <asm/tlbflush.h> << 22 << 23 static int << 24 page_set_nocache(pte_t *pte, unsigned long add << 25 unsigned long next, struct mm << 26 { 13 { 27 unsigned long cl; !! 14 cache_push(page_to_phys(page), size); 28 struct cpuinfo_or1k *cpuinfo = &cpuinf << 29 << 30 pte_val(*pte) |= _PAGE_CI; << 31 << 32 /* << 33 * Flush the page out of the TLB so th << 34 * picked up next time there's an acce << 35 */ << 36 flush_tlb_kernel_range(addr, addr + PA << 37 << 38 /* Flush page out of dcache */ << 39 for (cl = __pa(addr); cl < __pa(next); << 40 mtspr(SPR_DCBFR, cl); << 41 << 42 return 0; << 43 } 15 } 44 16 45 static const struct mm_walk_ops set_nocache_wa !! 17 pgprot_t pgprot_dmacoherent(pgprot_t prot) 46 .pte_entry = page_set_noc << 47 }; << 48 << 49 static int << 50 page_clear_nocache(pte_t *pte, unsigned long a << 51 unsigned long next, struct << 52 { 18 { 53 pte_val(*pte) &= ~_PAGE_CI; !! 19 if (CPU_IS_040_OR_060) { 54 !! 20 pgprot_val(prot) &= ~_PAGE_CACHE040; 55 /* !! 21 pgprot_val(prot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S; 56 * Flush the page out of the TLB so th !! 22 } else { 57 * picked up next time there's an acce !! 23 pgprot_val(prot) |= _PAGE_NOCACHE030; 58 */ !! 24 } 59 flush_tlb_kernel_range(addr, addr + PA !! 25 return prot; 60 << 61 return 0; << 62 } 26 } >> 27 #endif /* CONFIG_MMU && !CONFIG_COLDFIRE */ 63 28 64 static const struct mm_walk_ops clear_nocache_ !! 29 void arch_sync_dma_for_device(phys_addr_t handle, size_t size, 65 .pte_entry = page_clear_n << 66 }; << 67 << 68 void *arch_dma_set_uncached(void *cpu_addr, si << 69 { << 70 unsigned long va = (unsigned long)cpu_ << 71 int error; << 72 << 73 /* << 74 * We need to iterate through the page << 75 * them and setting the cache-inhibit << 76 */ << 77 mmap_write_lock(&init_mm); << 78 error = walk_page_range_novma(&init_mm << 79 &set_nocache_walk_ops, << 80 mmap_write_unlock(&init_mm); << 81 << 82 if (error) << 83 return ERR_PTR(error); << 84 return cpu_addr; << 85 } << 86 << 87 void arch_dma_clear_uncached(void *cpu_addr, s << 88 { << 89 unsigned long va = (unsigned long)cpu_ << 90 << 91 mmap_write_lock(&init_mm); << 92 /* walk_page_range shouldn't be able t << 93 WARN_ON(walk_page_range_novma(&init_mm << 94 &clear_nocache_walk_op << 95 mmap_write_unlock(&init_mm); << 96 } << 97 << 98 void arch_sync_dma_for_device(phys_addr_t addr << 99 enum dma_data_direction dir) 30 enum dma_data_direction dir) 100 { 31 { 101 unsigned long cl; << 102 struct cpuinfo_or1k *cpuinfo = &cpuinf << 103 << 104 switch (dir) { 32 switch (dir) { >> 33 case DMA_BIDIRECTIONAL: 105 case DMA_TO_DEVICE: 34 case DMA_TO_DEVICE: 106 /* Flush the dcache for the re !! 35 cache_push(handle, size); 107 for (cl = addr; cl < addr + si << 108 cl += cpuinfo->dcache_blo << 109 mtspr(SPR_DCBFR, cl); << 110 break; 36 break; 111 case DMA_FROM_DEVICE: 37 case DMA_FROM_DEVICE: 112 /* Invalidate the dcache for t !! 38 cache_clear(handle, size); 113 for (cl = addr; cl < addr + si << 114 cl += cpuinfo->dcache_blo << 115 mtspr(SPR_DCBIR, cl); << 116 break; 39 break; 117 default: 40 default: 118 /* !! 41 pr_err_ratelimited("dma_sync_single_for_device: unsupported dir %u\n", 119 * NOTE: If dir == DMA_BIDIREC !! 42 dir); 120 * flush nor invalidate the ca << 121 * to be manually synced anywa << 122 */ << 123 break; 43 break; 124 } 44 } 125 } 45 } 126 46
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.