xref: /OK3568_Linux_fs/kernel/arch/mips/mm/dma-noncoherent.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
4*4882a593Smuzhiyun  * Copyright (C) 2000, 2001, 06	 Ralf Baechle <ralf@linux-mips.org>
5*4882a593Smuzhiyun  * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun #include <linux/dma-direct.h>
8*4882a593Smuzhiyun #include <linux/dma-map-ops.h>
9*4882a593Smuzhiyun #include <linux/highmem.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <asm/cache.h>
12*4882a593Smuzhiyun #include <asm/cpu-type.h>
13*4882a593Smuzhiyun #include <asm/dma-coherence.h>
14*4882a593Smuzhiyun #include <asm/io.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun /*
17*4882a593Smuzhiyun  * The affected CPUs below in 'cpu_needs_post_dma_flush()' can speculatively
18*4882a593Smuzhiyun  * fill random cachelines with stale data at any time, requiring an extra
19*4882a593Smuzhiyun  * flush post-DMA.
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * Warning on the terminology - Linux calls an uncached area coherent;  MIPS
22*4882a593Smuzhiyun  * terminology calls memory areas with hardware maintained coherency coherent.
23*4882a593Smuzhiyun  *
24*4882a593Smuzhiyun  * Note that the R14000 and R16000 should also be checked for in this condition.
25*4882a593Smuzhiyun  * However this function is only called on non-I/O-coherent systems and only the
26*4882a593Smuzhiyun  * R10000 and R12000 are used in such systems, the SGI IP28 Indigo² rsp.
27*4882a593Smuzhiyun  * SGI IP32 aka O2.
28*4882a593Smuzhiyun  */
cpu_needs_post_dma_flush(void)29*4882a593Smuzhiyun static inline bool cpu_needs_post_dma_flush(void)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun 	switch (boot_cpu_type()) {
32*4882a593Smuzhiyun 	case CPU_R10000:
33*4882a593Smuzhiyun 	case CPU_R12000:
34*4882a593Smuzhiyun 	case CPU_BMIPS5000:
35*4882a593Smuzhiyun 	case CPU_LOONGSON2EF:
36*4882a593Smuzhiyun 		return true;
37*4882a593Smuzhiyun 	default:
38*4882a593Smuzhiyun 		/*
39*4882a593Smuzhiyun 		 * Presence of MAARs suggests that the CPU supports
40*4882a593Smuzhiyun 		 * speculatively prefetching data, and therefore requires
41*4882a593Smuzhiyun 		 * the post-DMA flush/invalidate.
42*4882a593Smuzhiyun 		 */
43*4882a593Smuzhiyun 		return cpu_has_maar;
44*4882a593Smuzhiyun 	}
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun 
arch_dma_prep_coherent(struct page * page,size_t size)47*4882a593Smuzhiyun void arch_dma_prep_coherent(struct page *page, size_t size)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun 	dma_cache_wback_inv((unsigned long)page_address(page), size);
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun 
arch_dma_set_uncached(void * addr,size_t size)52*4882a593Smuzhiyun void *arch_dma_set_uncached(void *addr, size_t size)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun 	return (void *)(__pa(addr) + UNCAC_BASE);
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
dma_sync_virt_for_device(void * addr,size_t size,enum dma_data_direction dir)57*4882a593Smuzhiyun static inline void dma_sync_virt_for_device(void *addr, size_t size,
58*4882a593Smuzhiyun 		enum dma_data_direction dir)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	switch (dir) {
61*4882a593Smuzhiyun 	case DMA_TO_DEVICE:
62*4882a593Smuzhiyun 		dma_cache_wback((unsigned long)addr, size);
63*4882a593Smuzhiyun 		break;
64*4882a593Smuzhiyun 	case DMA_FROM_DEVICE:
65*4882a593Smuzhiyun 		dma_cache_inv((unsigned long)addr, size);
66*4882a593Smuzhiyun 		break;
67*4882a593Smuzhiyun 	case DMA_BIDIRECTIONAL:
68*4882a593Smuzhiyun 		dma_cache_wback_inv((unsigned long)addr, size);
69*4882a593Smuzhiyun 		break;
70*4882a593Smuzhiyun 	default:
71*4882a593Smuzhiyun 		BUG();
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
dma_sync_virt_for_cpu(void * addr,size_t size,enum dma_data_direction dir)75*4882a593Smuzhiyun static inline void dma_sync_virt_for_cpu(void *addr, size_t size,
76*4882a593Smuzhiyun 		enum dma_data_direction dir)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun 	switch (dir) {
79*4882a593Smuzhiyun 	case DMA_TO_DEVICE:
80*4882a593Smuzhiyun 		break;
81*4882a593Smuzhiyun 	case DMA_FROM_DEVICE:
82*4882a593Smuzhiyun 	case DMA_BIDIRECTIONAL:
83*4882a593Smuzhiyun 		dma_cache_inv((unsigned long)addr, size);
84*4882a593Smuzhiyun 		break;
85*4882a593Smuzhiyun 	default:
86*4882a593Smuzhiyun 		BUG();
87*4882a593Smuzhiyun 	}
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun /*
91*4882a593Smuzhiyun  * A single sg entry may refer to multiple physically contiguous pages.  But
92*4882a593Smuzhiyun  * we still need to process highmem pages individually.  If highmem is not
93*4882a593Smuzhiyun  * configured then the bulk of this loop gets optimized out.
94*4882a593Smuzhiyun  */
dma_sync_phys(phys_addr_t paddr,size_t size,enum dma_data_direction dir,bool for_device)95*4882a593Smuzhiyun static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
96*4882a593Smuzhiyun 		enum dma_data_direction dir, bool for_device)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
99*4882a593Smuzhiyun 	unsigned long offset = paddr & ~PAGE_MASK;
100*4882a593Smuzhiyun 	size_t left = size;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	do {
103*4882a593Smuzhiyun 		size_t len = left;
104*4882a593Smuzhiyun 		void *addr;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 		if (PageHighMem(page)) {
107*4882a593Smuzhiyun 			if (offset + len > PAGE_SIZE)
108*4882a593Smuzhiyun 				len = PAGE_SIZE - offset;
109*4882a593Smuzhiyun 		}
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 		addr = kmap_atomic(page);
112*4882a593Smuzhiyun 		if (for_device)
113*4882a593Smuzhiyun 			dma_sync_virt_for_device(addr + offset, len, dir);
114*4882a593Smuzhiyun 		else
115*4882a593Smuzhiyun 			dma_sync_virt_for_cpu(addr + offset, len, dir);
116*4882a593Smuzhiyun 		kunmap_atomic(addr);
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 		offset = 0;
119*4882a593Smuzhiyun 		page++;
120*4882a593Smuzhiyun 		left -= len;
121*4882a593Smuzhiyun 	} while (left);
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun 
arch_sync_dma_for_device(phys_addr_t paddr,size_t size,enum dma_data_direction dir)124*4882a593Smuzhiyun void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
125*4882a593Smuzhiyun 		enum dma_data_direction dir)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun 	dma_sync_phys(paddr, size, dir, true);
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun #ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
arch_sync_dma_for_cpu(phys_addr_t paddr,size_t size,enum dma_data_direction dir)131*4882a593Smuzhiyun void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
132*4882a593Smuzhiyun 		enum dma_data_direction dir)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun 	if (cpu_needs_post_dma_flush())
135*4882a593Smuzhiyun 		dma_sync_phys(paddr, size, dir, false);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun #endif
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun #ifdef CONFIG_DMA_PERDEV_COHERENT
arch_setup_dma_ops(struct device * dev,u64 dma_base,u64 size,const struct iommu_ops * iommu,bool coherent)140*4882a593Smuzhiyun void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
141*4882a593Smuzhiyun 		const struct iommu_ops *iommu, bool coherent)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun 	dev->dma_coherent = coherent;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun #endif
146