Merge branches 'at91', 'ep93xx', 'kexec', 'iop', 'lmb', 'nomadik', 'nuc', 'pl', ...
[sfrench/cifs-2.6.git] / arch / arm / mm / proc-mohawk.S
1 /*
2  *  linux/arch/arm/mm/proc-mohawk.S: MMU functions for Marvell PJ1 core
3  *
4  *  PJ1 (codename Mohawk) is a hybrid of the xscale3 and Marvell's own core.
5  *
6  *  Heavily based on proc-arm926.S and proc-xsc3.S
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <linux/linkage.h>
24 #include <linux/init.h>
25 #include <asm/assembler.h>
26 #include <asm/hwcap.h>
27 #include <asm/pgtable-hwdef.h>
28 #include <asm/pgtable.h>
29 #include <asm/page.h>
30 #include <asm/ptrace.h>
31 #include "proc-macros.S"
32
33 /*
34  * This is the maximum size of an area which will be flushed.  If the
35  * area is larger than this, then we flush the whole cache.
36  */
37 #define CACHE_DLIMIT    32768
38
39 /*
40  * The cache line size of the L1 D cache.
41  */
42 #define CACHE_DLINESIZE 32
43
44 /*
45  * cpu_mohawk_proc_init()
46  */
47 ENTRY(cpu_mohawk_proc_init)
48         mov     pc, lr
49
50 /*
51  * cpu_mohawk_proc_fin()
52  */
53 ENTRY(cpu_mohawk_proc_fin)
54         stmfd   sp!, {lr}
55         mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
56         msr     cpsr_c, ip
57         bl      mohawk_flush_kern_cache_all
58         mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
59         bic     r0, r0, #0x1800                 @ ...iz...........
60         bic     r0, r0, #0x0006                 @ .............ca.
61         mcr     p15, 0, r0, c1, c0, 0           @ disable caches
62         ldmfd   sp!, {pc}
63
64 /*
65  * cpu_mohawk_reset(loc)
66  *
67  * Perform a soft reset of the system.  Put the CPU into the
68  * same state as it would be if it had been reset, and branch
69  * to what would be the reset vector.
70  *
71  * loc: location to jump to for soft reset
72  *
73  * (same as arm926)
74  */
75         .align  5
76 ENTRY(cpu_mohawk_reset)
77         mov     ip, #0
78         mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches
79         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
80         mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
81         mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
82         bic     ip, ip, #0x0007                 @ .............cam
83         bic     ip, ip, #0x1100                 @ ...i...s........
84         mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
85         mov     pc, r0
86
87 /*
88  * cpu_mohawk_do_idle()
89  *
90  * Called with IRQs disabled
91  */
92         .align  5
93 ENTRY(cpu_mohawk_do_idle)
94         mov     r0, #0
95         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
96         mcr     p15, 0, r0, c7, c0, 4           @ wait for interrupt
97         mov     pc, lr
98
99 /*
100  *      flush_user_cache_all()
101  *
102  *      Clean and invalidate all cache entries in a particular
103  *      address space.
104  */
105 ENTRY(mohawk_flush_user_cache_all)
106         /* FALLTHROUGH */
107
108 /*
109  *      flush_kern_cache_all()
110  *
111  *      Clean and invalidate the entire cache.
112  */
113 ENTRY(mohawk_flush_kern_cache_all)
114         mov     r2, #VM_EXEC
115         mov     ip, #0
116 __flush_whole_cache:
117         mcr     p15, 0, ip, c7, c14, 0          @ clean & invalidate all D cache
118         tst     r2, #VM_EXEC
119         mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
120         mcrne   p15, 0, ip, c7, c10, 0          @ drain write buffer
121         mov     pc, lr
122
123 /*
124  *      flush_user_cache_range(start, end, flags)
125  *
126  *      Clean and invalidate a range of cache entries in the
127  *      specified address range.
128  *
129  *      - start - start address (inclusive)
130  *      - end   - end address (exclusive)
131  *      - flags - vm_flags describing address space
132  *
133  * (same as arm926)
134  */
135 ENTRY(mohawk_flush_user_cache_range)
136         mov     ip, #0
137         sub     r3, r1, r0                      @ calculate total size
138         cmp     r3, #CACHE_DLIMIT
139         bgt     __flush_whole_cache
140 1:      tst     r2, #VM_EXEC
141         mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
142         mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
143         add     r0, r0, #CACHE_DLINESIZE
144         mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
145         mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
146         add     r0, r0, #CACHE_DLINESIZE
147         cmp     r0, r1
148         blo     1b
149         tst     r2, #VM_EXEC
150         mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
151         mov     pc, lr
152
153 /*
154  *      coherent_kern_range(start, end)
155  *
156  *      Ensure coherency between the Icache and the Dcache in the
157  *      region described by start, end.  If you have non-snooping
158  *      Harvard caches, you need to implement this function.
159  *
160  *      - start - virtual start address
161  *      - end   - virtual end address
162  */
163 ENTRY(mohawk_coherent_kern_range)
164         /* FALLTHROUGH */
165
166 /*
167  *      coherent_user_range(start, end)
168  *
169  *      Ensure coherency between the Icache and the Dcache in the
170  *      region described by start, end.  If you have non-snooping
171  *      Harvard caches, you need to implement this function.
172  *
173  *      - start - virtual start address
174  *      - end   - virtual end address
175  *
176  * (same as arm926)
177  */
178 ENTRY(mohawk_coherent_user_range)
179         bic     r0, r0, #CACHE_DLINESIZE - 1
180 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
181         mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
182         add     r0, r0, #CACHE_DLINESIZE
183         cmp     r0, r1
184         blo     1b
185         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
186         mov     pc, lr
187
188 /*
189  *      flush_kern_dcache_area(void *addr, size_t size)
190  *
191  *      Ensure no D cache aliasing occurs, either with itself or
192  *      the I cache
193  *
194  *      - addr  - kernel address
195  *      - size  - region size
196  */
197 ENTRY(mohawk_flush_kern_dcache_area)
198         add     r1, r0, r1
199 1:      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, c5, 0           @ invalidate I cache
205         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
206         mov     pc, lr
207
208 /*
209  *      dma_inv_range(start, end)
210  *
211  *      Invalidate (discard) the specified virtual address range.
212  *      May not write back any entries.  If 'start' or 'end'
213  *      are not cache line aligned, those lines must be written
214  *      back.
215  *
216  *      - start - virtual start address
217  *      - end   - virtual end address
218  *
219  * (same as v4wb)
220  */
221 mohawk_dma_inv_range:
222         tst     r0, #CACHE_DLINESIZE - 1
223         mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
224         tst     r1, #CACHE_DLINESIZE - 1
225         mcrne   p15, 0, r1, c7, c10, 1          @ clean D entry
226         bic     r0, r0, #CACHE_DLINESIZE - 1
227 1:      mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
228         add     r0, r0, #CACHE_DLINESIZE
229         cmp     r0, r1
230         blo     1b
231         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
232         mov     pc, lr
233
234 /*
235  *      dma_clean_range(start, end)
236  *
237  *      Clean the specified virtual address range.
238  *
239  *      - start - virtual start address
240  *      - end   - virtual end address
241  *
242  * (same as v4wb)
243  */
244 mohawk_dma_clean_range:
245         bic     r0, r0, #CACHE_DLINESIZE - 1
246 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
247         add     r0, r0, #CACHE_DLINESIZE
248         cmp     r0, r1
249         blo     1b
250         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
251         mov     pc, lr
252
253 /*
254  *      dma_flush_range(start, end)
255  *
256  *      Clean and invalidate the specified virtual address range.
257  *
258  *      - start - virtual start address
259  *      - end   - virtual end address
260  */
261 ENTRY(mohawk_dma_flush_range)
262         bic     r0, r0, #CACHE_DLINESIZE - 1
263 1:
264         mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
265         add     r0, r0, #CACHE_DLINESIZE
266         cmp     r0, r1
267         blo     1b
268         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
269         mov     pc, lr
270
271 /*
272  *      dma_map_area(start, size, dir)
273  *      - start - kernel virtual start address
274  *      - size  - size of region
275  *      - dir   - DMA direction
276  */
277 ENTRY(mohawk_dma_map_area)
278         add     r1, r1, r0
279         cmp     r2, #DMA_TO_DEVICE
280         beq     mohawk_dma_clean_range
281         bcs     mohawk_dma_inv_range
282         b       mohawk_dma_flush_range
283 ENDPROC(mohawk_dma_map_area)
284
285 /*
286  *      dma_unmap_area(start, size, dir)
287  *      - start - kernel virtual start address
288  *      - size  - size of region
289  *      - dir   - DMA direction
290  */
291 ENTRY(mohawk_dma_unmap_area)
292         mov     pc, lr
293 ENDPROC(mohawk_dma_unmap_area)
294
295 ENTRY(mohawk_cache_fns)
296         .long   mohawk_flush_kern_cache_all
297         .long   mohawk_flush_user_cache_all
298         .long   mohawk_flush_user_cache_range
299         .long   mohawk_coherent_kern_range
300         .long   mohawk_coherent_user_range
301         .long   mohawk_flush_kern_dcache_area
302         .long   mohawk_dma_map_area
303         .long   mohawk_dma_unmap_area
304         .long   mohawk_dma_flush_range
305
306 ENTRY(cpu_mohawk_dcache_clean_area)
307 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
308         add     r0, r0, #CACHE_DLINESIZE
309         subs    r1, r1, #CACHE_DLINESIZE
310         bhi     1b
311         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
312         mov     pc, lr
313
314 /*
315  * cpu_mohawk_switch_mm(pgd)
316  *
317  * Set the translation base pointer to be as described by pgd.
318  *
319  * pgd: new page tables
320  */
321         .align  5
322 ENTRY(cpu_mohawk_switch_mm)
323         mov     ip, #0
324         mcr     p15, 0, ip, c7, c14, 0          @ clean & invalidate all D cache
325         mcr     p15, 0, ip, c7, c5, 0           @ invalidate I cache
326         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
327         orr     r0, r0, #0x18                   @ cache the page table in L2
328         mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
329         mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
330         mov     pc, lr
331
332 /*
333  * cpu_mohawk_set_pte_ext(ptep, pte, ext)
334  *
335  * Set a PTE and flush it out
336  */
337         .align  5
338 ENTRY(cpu_mohawk_set_pte_ext)
339         armv3_set_pte_ext
340         mov     r0, r0
341         mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
342         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
343         mov     pc, lr
344
345         __INIT
346
347         .type   __mohawk_setup, #function
348 __mohawk_setup:
349         mov     r0, #0
350         mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches
351         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
352         mcr     p15, 0, r0, c8, c7              @ invalidate I,D TLBs
353         orr     r4, r4, #0x18                   @ cache the page table in L2
354         mcr     p15, 0, r4, c2, c0, 0           @ load page table pointer
355
356         mov     r0, #0                          @ don't allow CP access
357         mcr     p15, 0, r0, c15, c1, 0          @ write CP access register
358
359         adr     r5, mohawk_crval
360         ldmia   r5, {r5, r6}
361         mrc     p15, 0, r0, c1, c0              @ get control register
362         bic     r0, r0, r5
363         orr     r0, r0, r6
364         mov     pc, lr
365
366         .size   __mohawk_setup, . - __mohawk_setup
367
368         /*
369          *  R
370          * .RVI ZFRS BLDP WCAM
371          * .011 1001 ..00 0101
372          *
373          */
374         .type   mohawk_crval, #object
375 mohawk_crval:
376         crval   clear=0x00007f3f, mmuset=0x00003905, ucset=0x00001134
377
378         __INITDATA
379
380 /*
381  * Purpose : Function pointers used to access above functions - all calls
382  *           come through these
383  */
384         .type   mohawk_processor_functions, #object
385 mohawk_processor_functions:
386         .word   v5t_early_abort
387         .word   legacy_pabort
388         .word   cpu_mohawk_proc_init
389         .word   cpu_mohawk_proc_fin
390         .word   cpu_mohawk_reset
391         .word   cpu_mohawk_do_idle
392         .word   cpu_mohawk_dcache_clean_area
393         .word   cpu_mohawk_switch_mm
394         .word   cpu_mohawk_set_pte_ext
395         .size   mohawk_processor_functions, . - mohawk_processor_functions
396
397         .section ".rodata"
398
399         .type   cpu_arch_name, #object
400 cpu_arch_name:
401         .asciz  "armv5te"
402         .size   cpu_arch_name, . - cpu_arch_name
403
404         .type   cpu_elf_name, #object
405 cpu_elf_name:
406         .asciz  "v5"
407         .size   cpu_elf_name, . - cpu_elf_name
408
409         .type   cpu_mohawk_name, #object
410 cpu_mohawk_name:
411         .asciz  "Marvell 88SV331x"
412         .size   cpu_mohawk_name, . - cpu_mohawk_name
413
414         .align
415
416         .section ".proc.info.init", #alloc, #execinstr
417
418         .type   __88sv331x_proc_info,#object
419 __88sv331x_proc_info:
420         .long   0x56158000                      @ Marvell 88SV331x (MOHAWK)
421         .long   0xfffff000
422         .long   PMD_TYPE_SECT | \
423                 PMD_SECT_BUFFERABLE | \
424                 PMD_SECT_CACHEABLE | \
425                 PMD_BIT4 | \
426                 PMD_SECT_AP_WRITE | \
427                 PMD_SECT_AP_READ
428         .long   PMD_TYPE_SECT | \
429                 PMD_BIT4 | \
430                 PMD_SECT_AP_WRITE | \
431                 PMD_SECT_AP_READ
432         b       __mohawk_setup
433         .long   cpu_arch_name
434         .long   cpu_elf_name
435         .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
436         .long   cpu_mohawk_name
437         .long   mohawk_processor_functions
438         .long   v4wbi_tlb_fns
439         .long   v4wb_user_fns
440         .long   mohawk_cache_fns
441         .size   __88sv331x_proc_info, . - __88sv331x_proc_info