• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/arm/mm/
1/*
2 *  linux/arch/arm/mm/cache-fa.S
3 *
4 *  Copyright (C) 2005 Faraday Corp.
5 *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
6 *
7 * Based on cache-v4wb.S:
8 *  Copyright (C) 1997-2002 Russell king
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 *  Processors: FA520 FA526 FA626
15 */
16#include <linux/linkage.h>
17#include <linux/init.h>
18#include <asm/memory.h>
19#include <asm/page.h>
20
21#include "proc-macros.S"
22
23/*
24 * The size of one data cache line.
25 */
26#define CACHE_DLINESIZE	16
27
28/*
29 * The total size of the data cache.
30 */
31#ifdef CONFIG_ARCH_GEMINI
32#define CACHE_DSIZE	8192
33#else
34#define CACHE_DSIZE	16384
35#endif
36
37#define CACHE_DLIMIT	(CACHE_DSIZE * 2)
38
39/*
40 *	flush_user_cache_all()
41 *
42 *	Clean and invalidate all cache entries in a particular address
43 *	space.
44 */
45ENTRY(fa_flush_user_cache_all)
46	/* FALLTHROUGH */
47/*
48 *	flush_kern_cache_all()
49 *
50 *	Clean and invalidate the entire cache.
51 */
52ENTRY(fa_flush_kern_cache_all)
53	mov	ip, #0
54	mov	r2, #VM_EXEC
55__flush_whole_cache:
56	mcr	p15, 0, ip, c7, c14, 0		@ clean/invalidate D cache
57	tst	r2, #VM_EXEC
58	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
59	mcrne	p15, 0, ip, c7, c5, 6		@ invalidate BTB
60	mcrne	p15, 0, ip, c7, c10, 4		@ drain write buffer
61	mcrne	p15, 0, ip, c7, c5, 4		@ prefetch flush
62	mov	pc, lr
63
64/*
65 *	flush_user_cache_range(start, end, flags)
66 *
67 *	Invalidate a range of cache entries in the specified
68 *	address space.
69 *
70 *	- start - start address (inclusive, page aligned)
71 *	- end	- end address (exclusive, page aligned)
72 *	- flags	- vma_area_struct flags describing address space
73 */
74ENTRY(fa_flush_user_cache_range)
75	mov	ip, #0
76	sub	r3, r1, r0			@ calculate total size
77	cmp	r3, #CACHE_DLIMIT		@ total size >= limit?
78	bhs	__flush_whole_cache		@ flush whole D cache
79
801:	tst	r2, #VM_EXEC
81	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I line
82	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
83	add	r0, r0, #CACHE_DLINESIZE
84	cmp	r0, r1
85	blo	1b
86	tst	r2, #VM_EXEC
87	mcrne	p15, 0, ip, c7, c5, 6		@ invalidate BTB
88	mcrne	p15, 0, ip, c7, c10, 4		@ data write barrier
89	mcrne	p15, 0, ip, c7, c5, 4		@ prefetch flush
90	mov	pc, lr
91
92/*
93 *	coherent_kern_range(start, end)
94 *
95 *	Ensure coherency between the Icache and the Dcache in the
96 *	region described by start.  If you have non-snooping
97 *	Harvard caches, you need to implement this function.
98 *
99 *	- start  - virtual start address
100 *	- end	 - virtual end address
101 */
102ENTRY(fa_coherent_kern_range)
103	/* fall through */
104
105/*
106 *	coherent_user_range(start, end)
107 *
108 *	Ensure coherency between the Icache and the Dcache in the
109 *	region described by start.  If you have non-snooping
110 *	Harvard caches, you need to implement this function.
111 *
112 *	- start  - virtual start address
113 *	- end	 - virtual end address
114 */
115ENTRY(fa_coherent_user_range)
116	bic	r0, r0, #CACHE_DLINESIZE - 1
1171:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
118	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
119	add	r0, r0, #CACHE_DLINESIZE
120	cmp	r0, r1
121	blo	1b
122	mov	r0, #0
123	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB
124	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
125	mcr	p15, 0, r0, c7, c5, 4		@ prefetch flush
126	mov	pc, lr
127
128/*
129 *	flush_kern_dcache_area(void *addr, size_t size)
130 *
131 *	Ensure that the data held in the page kaddr is written back
132 *	to the page in question.
133 *
134 *	- addr	- kernel address
135 *	- size	- size of region
136 */
137ENTRY(fa_flush_kern_dcache_area)
138	add	r1, r0, r1
1391:	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
140	add	r0, r0, #CACHE_DLINESIZE
141	cmp	r0, r1
142	blo	1b
143	mov	r0, #0
144	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
145	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
146	mov	pc, lr
147
148/*
149 *	dma_inv_range(start, end)
150 *
151 *	Invalidate (discard) the specified virtual address range.
152 *	May not write back any entries.  If 'start' or 'end'
153 *	are not cache line aligned, those lines must be written
154 *	back.
155 *
156 *	- start  - virtual start address
157 *	- end	 - virtual end address
158 */
159fa_dma_inv_range:
160	tst	r0, #CACHE_DLINESIZE - 1
161	bic	r0, r0, #CACHE_DLINESIZE - 1
162	mcrne	p15, 0, r0, c7, c14, 1		@ clean & invalidate D entry
163	tst	r1, #CACHE_DLINESIZE - 1
164	bic	r1, r1, #CACHE_DLINESIZE - 1
165	mcrne	p15, 0, r1, c7, c14, 1		@ clean & invalidate D entry
1661:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
167	add	r0, r0, #CACHE_DLINESIZE
168	cmp	r0, r1
169	blo	1b
170	mov	r0, #0
171	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
172	mov	pc, lr
173
174/*
175 *	dma_clean_range(start, end)
176 *
177 *	Clean (write back) the specified virtual address range.
178 *
179 *	- start  - virtual start address
180 *	- end	 - virtual end address
181 */
182fa_dma_clean_range:
183	bic	r0, r0, #CACHE_DLINESIZE - 1
1841:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
185	add	r0, r0, #CACHE_DLINESIZE
186	cmp	r0, r1
187	blo	1b
188	mov	r0, #0
189	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
190	mov	pc, lr
191
192/*
193 *	dma_flush_range(start,end)
194 *	- start   - virtual start address of region
195 *	- end     - virtual end address of region
196 */
197ENTRY(fa_dma_flush_range)
198	bic	r0, r0, #CACHE_DLINESIZE - 1
1991:	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D entry
200	add	r0, r0, #CACHE_DLINESIZE
201	cmp	r0, r1
202	blo	1b
203	mov	r0, #0
204	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
205	mov	pc, lr
206
207/*
208 *	dma_map_area(start, size, dir)
209 *	- start	- kernel virtual start address
210 *	- size	- size of region
211 *	- dir	- DMA direction
212 */
213ENTRY(fa_dma_map_area)
214	add	r1, r1, r0
215	cmp	r2, #DMA_TO_DEVICE
216	beq	fa_dma_clean_range
217	bcs	fa_dma_inv_range
218	b	fa_dma_flush_range
219ENDPROC(fa_dma_map_area)
220
221/*
222 *	dma_unmap_area(start, size, dir)
223 *	- start	- kernel virtual start address
224 *	- size	- size of region
225 *	- dir	- DMA direction
226 */
227ENTRY(fa_dma_unmap_area)
228	mov	pc, lr
229ENDPROC(fa_dma_unmap_area)
230
231	__INITDATA
232
233	.type	fa_cache_fns, #object
234ENTRY(fa_cache_fns)
235	.long	fa_flush_kern_cache_all
236	.long	fa_flush_user_cache_all
237	.long	fa_flush_user_cache_range
238	.long	fa_coherent_kern_range
239	.long	fa_coherent_user_range
240	.long	fa_flush_kern_dcache_area
241	.long	fa_dma_map_area
242	.long	fa_dma_unmap_area
243	.long	fa_dma_flush_range
244	.size	fa_cache_fns, . - fa_cache_fns
245