xref: /linux/arch/arm/mm/proc-sa1100.S (revision ccea15f45eb0ab12d658f88b5d4be005cb2bb1a7)
1/*
2 *  linux/arch/arm/mm/proc-sa1100.S
3 *
4 *  Copyright (C) 1997-2002 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 *  MMU functions for SA110
11 *
12 *  These are the low level assembler for performing cache and TLB
13 *  functions on the StrongARM-1100 and StrongARM-1110.
14 *
15 *  Note that SA1100 and SA1110 share everything but their name and CPU ID.
16 *
17 *  12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
18 *    Flush the read buffer at context switches
19 */
20#include <linux/linkage.h>
21#include <linux/init.h>
22#include <asm/assembler.h>
23#include <asm/asm-offsets.h>
24#include <asm/procinfo.h>
25#include <asm/hardware.h>
26#include <asm/pgtable-hwdef.h>
27#include <asm/pgtable.h>
28
29/*
30 * the cache line size of the I and D cache
31 */
32#define DCACHELINESIZE	32
33
34	__INIT
35
36/*
37 * cpu_sa1100_proc_init()
38 */
39ENTRY(cpu_sa1100_proc_init)
40	mov	r0, #0
41	mcr	p15, 0, r0, c15, c1, 2		@ Enable clock switching
42	mcr	p15, 0, r0, c9, c0, 5		@ Allow read-buffer operations from userland
43	mov	pc, lr
44
45	.previous
46
47/*
48 * cpu_sa1100_proc_fin()
49 *
50 * Prepare the CPU for reset:
51 *  - Disable interrupts
52 *  - Clean and turn off caches.
53 */
54ENTRY(cpu_sa1100_proc_fin)
55	stmfd	sp!, {lr}
56	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
57	msr	cpsr_c, ip
58	bl	v4wb_flush_kern_cache_all
59	mcr	p15, 0, ip, c15, c2, 2		@ Disable clock switching
60	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
61	bic	r0, r0, #0x1000			@ ...i............
62	bic	r0, r0, #0x000e			@ ............wca.
63	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
64	ldmfd	sp!, {pc}
65
66/*
67 * cpu_sa1100_reset(loc)
68 *
69 * Perform a soft reset of the system.  Put the CPU into the
70 * same state as it would be if it had been reset, and branch
71 * to what would be the reset vector.
72 *
73 * loc: location to jump to for soft reset
74 */
75	.align	5
76ENTRY(cpu_sa1100_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, #0x000f			@ ............wcam
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_sa1100_do_idle(type)
89 *
90 * Cause the processor to idle
91 *
92 * type: call type:
93 *   0 = slow idle
94 *   1 = fast idle
95 *   2 = switch to slow processor clock
96 *   3 = switch to fast processor clock
97 */
98	.align	5
99ENTRY(cpu_sa1100_do_idle)
100	mov	r0, r0				@ 4 nop padding
101	mov	r0, r0
102	mov	r0, r0
103	mov	r0, r0				@ 4 nop padding
104	mov	r0, r0
105	mov	r0, r0
106	mov	r0, #0
107	ldr	r1, =UNCACHEABLE_ADDR		@ ptr to uncacheable address
108	@ --- aligned to a cache line
109	mcr	p15, 0, r0, c15, c2, 2		@ disable clock switching
110	ldr	r1, [r1, #0]			@ force switch to MCLK
111	mcr	p15, 0, r0, c15, c8, 2		@ wait for interrupt
112	mov	r0, r0				@ safety
113	mcr	p15, 0, r0, c15, c1, 2		@ enable clock switching
114	mov	pc, lr
115
116/* ================================= CACHE ================================ */
117
118/*
119 * cpu_sa1100_dcache_clean_area(addr,sz)
120 *
121 * Clean the specified entry of any caches such that the MMU
122 * translation fetches will obtain correct data.
123 *
124 * addr: cache-unaligned virtual address
125 */
126	.align	5
127ENTRY(cpu_sa1100_dcache_clean_area)
1281:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
129	add	r0, r0, #DCACHELINESIZE
130	subs	r1, r1, #DCACHELINESIZE
131	bhi	1b
132	mov	pc, lr
133
134/* =============================== PageTable ============================== */
135
136/*
137 * cpu_sa1100_switch_mm(pgd)
138 *
139 * Set the translation base pointer to be as described by pgd.
140 *
141 * pgd: new page tables
142 */
143	.align	5
144ENTRY(cpu_sa1100_switch_mm)
145	str	lr, [sp, #-4]!
146	bl	v4wb_flush_kern_cache_all	@ clears IP
147	mcr	p15, 0, ip, c9, c0, 0		@ invalidate RB
148	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
149	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
150	ldr	pc, [sp], #4
151
152/*
153 * cpu_sa1100_set_pte(ptep, pte)
154 *
155 * Set a PTE and flush it out
156 */
157	.align	5
158ENTRY(cpu_sa1100_set_pte)
159	str	r1, [r0], #-2048		@ linux version
160
161	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
162
163	bic	r2, r1, #PTE_SMALL_AP_MASK
164	bic	r2, r2, #PTE_TYPE_MASK
165	orr	r2, r2, #PTE_TYPE_SMALL
166
167	tst	r1, #L_PTE_USER			@ User?
168	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
169
170	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
171	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
172
173	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
174	movne	r2, #0
175
176	str	r2, [r0]			@ hardware version
177	mov	r0, r0
178	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
179	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
180	mov	pc, lr
181
182	__INIT
183
184	.type	__sa1100_setup, #function
185__sa1100_setup:
186	mov	r0, #0
187	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
188	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
189	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
190	mrc	p15, 0, r0, c1, c0		@ get control register v4
191	ldr	r5, sa1100_cr1_clear
192	bic	r0, r0, r5
193	ldr	r5, sa1100_cr1_set
194	orr	r0, r0, r5
195	mov	pc, lr
196	.size	__sa1100_setup, . - __sa1100_setup
197
198	/*
199	 *  R
200	 * .RVI ZFRS BLDP WCAM
201	 * ..11 0001 ..11 1101
202	 *
203	 */
204	.type	sa1100_cr1_clear, #object
205	.type	sa1100_cr1_set, #object
206sa1100_cr1_clear:
207	.word	0x3f3f
208sa1100_cr1_set:
209	.word	0x313d
210
211	__INITDATA
212
213/*
214 * Purpose : Function pointers used to access above functions - all calls
215 *	     come through these
216 */
217
218/*
219 * SA1100 and SA1110 share the same function calls
220 */
221	.type	sa1100_processor_functions, #object
222ENTRY(sa1100_processor_functions)
223	.word	v4_early_abort
224	.word	cpu_sa1100_proc_init
225	.word	cpu_sa1100_proc_fin
226	.word	cpu_sa1100_reset
227	.word	cpu_sa1100_do_idle
228	.word	cpu_sa1100_dcache_clean_area
229	.word	cpu_sa1100_switch_mm
230	.word	cpu_sa1100_set_pte
231	.size	sa1100_processor_functions, . - sa1100_processor_functions
232
233	.section ".rodata"
234
235	.type	cpu_arch_name, #object
236cpu_arch_name:
237	.asciz	"armv4"
238	.size	cpu_arch_name, . - cpu_arch_name
239
240	.type	cpu_elf_name, #object
241cpu_elf_name:
242	.asciz	"v4"
243	.size	cpu_elf_name, . - cpu_elf_name
244
245	.type	cpu_sa1100_name, #object
246cpu_sa1100_name:
247	.asciz	"StrongARM-1100"
248	.size	cpu_sa1100_name, . - cpu_sa1100_name
249
250	.type	cpu_sa1110_name, #object
251cpu_sa1110_name:
252	.asciz	"StrongARM-1110"
253	.size	cpu_sa1110_name, . - cpu_sa1110_name
254
255	.align
256
257	.section ".proc.info.init", #alloc, #execinstr
258
259	.type	__sa1100_proc_info,#object
260__sa1100_proc_info:
261	.long	0x4401a110
262	.long	0xfffffff0
263	.long   PMD_TYPE_SECT | \
264		PMD_SECT_BUFFERABLE | \
265		PMD_SECT_CACHEABLE | \
266		PMD_SECT_AP_WRITE | \
267		PMD_SECT_AP_READ
268	b	__sa1100_setup
269	.long	cpu_arch_name
270	.long	cpu_elf_name
271	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
272	.long	cpu_sa1100_name
273	.long	sa1100_processor_functions
274	.long	v4wb_tlb_fns
275	.long	v4_mc_user_fns
276	.long	v4wb_cache_fns
277	.size	__sa1100_proc_info, . - __sa1100_proc_info
278
279	.type	__sa1110_proc_info,#object
280__sa1110_proc_info:
281	.long	0x6901b110
282	.long	0xfffffff0
283	.long   PMD_TYPE_SECT | \
284		PMD_SECT_BUFFERABLE | \
285		PMD_SECT_CACHEABLE | \
286		PMD_SECT_AP_WRITE | \
287		PMD_SECT_AP_READ
288	b	__sa1100_setup
289	.long	cpu_arch_name
290	.long	cpu_elf_name
291	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
292	.long	cpu_sa1110_name
293	.long	sa1100_processor_functions
294	.long	v4wb_tlb_fns
295	.long	v4_mc_user_fns
296	.long	v4wb_cache_fns
297	.size	__sa1110_proc_info, . - __sa1110_proc_info
298