0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/linkage.h>
0019 #include <linux/init.h>
0020 #include <linux/pgtable.h>
0021 #include <asm/assembler.h>
0022 #include <asm/asm-offsets.h>
0023 #include <asm/hwcap.h>
0024 #include <mach/hardware.h>
0025 #include <asm/pgtable-hwdef.h>
0026
0027 #include "proc-macros.S"
0028
0029
0030
0031
0032 #define DCACHELINESIZE 32
0033
0034 .section .text
0035
0036
0037
0038
0039 ENTRY(cpu_sa1100_proc_init)
0040 mov r0, #0
0041 mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
0042 mcr p15, 0, r0, c9, c0, 5 @ Allow read-buffer operations from userland
0043 ret lr
0044
0045
0046
0047
0048
0049
0050
0051
0052 ENTRY(cpu_sa1100_proc_fin)
0053 mcr p15, 0, ip, c15, c2, 2 @ Disable clock switching
0054 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
0055 bic r0, r0, #0x1000 @ ...i............
0056 bic r0, r0, #0x000e @ ............wca.
0057 mcr p15, 0, r0, c1, c0, 0 @ disable caches
0058 ret lr
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 .align 5
0070 .pushsection .idmap.text, "ax"
0071 ENTRY(cpu_sa1100_reset)
0072 mov ip, #0
0073 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
0074 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0075 #ifdef CONFIG_MMU
0076 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
0077 #endif
0078 mrc p15, 0, ip, c1, c0, 0 @ ctrl register
0079 bic ip, ip, #0x000f @ ............wcam
0080 bic ip, ip, #0x1100 @ ...i...s........
0081 mcr p15, 0, ip, c1, c0, 0 @ ctrl register
0082 ret r0
0083 ENDPROC(cpu_sa1100_reset)
0084 .popsection
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 .align 5
0098 ENTRY(cpu_sa1100_do_idle)
0099 mov r0, r0 @ 4 nop padding
0100 mov r0, r0
0101 mov r0, r0
0102 mov r0, r0 @ 4 nop padding
0103 mov r0, r0
0104 mov r0, r0
0105 mov r0, #0
0106 ldr r1, =UNCACHEABLE_ADDR @ ptr to uncacheable address
0107 @ --- aligned to a cache line
0108 mcr p15, 0, r0, c15, c2, 2 @ disable clock switching
0109 ldr r1, [r1, #0] @ force switch to MCLK
0110 mcr p15, 0, r0, c15, c8, 2 @ wait for interrupt
0111 mov r0, r0 @ safety
0112 mcr p15, 0, r0, c15, c1, 2 @ enable clock switching
0113 ret lr
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 .align 5
0126 ENTRY(cpu_sa1100_dcache_clean_area)
0127 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0128 add r0, r0, #DCACHELINESIZE
0129 subs r1, r1, #DCACHELINESIZE
0130 bhi 1b
0131 ret lr
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 .align 5
0143 ENTRY(cpu_sa1100_switch_mm)
0144 #ifdef CONFIG_MMU
0145 str lr, [sp, #-4]!
0146 bl v4wb_flush_kern_cache_all @ clears IP
0147 mcr p15, 0, ip, c9, c0, 0 @ invalidate RB
0148 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
0149 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
0150 ldr pc, [sp], #4
0151 #else
0152 ret lr
0153 #endif
0154
0155
0156
0157
0158
0159
0160 .align 5
0161 ENTRY(cpu_sa1100_set_pte_ext)
0162 #ifdef CONFIG_MMU
0163 armv3_set_pte_ext wc_disable=0
0164 mov r0, r0
0165 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0166 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0167 #endif
0168 ret lr
0169
0170 .globl cpu_sa1100_suspend_size
0171 .equ cpu_sa1100_suspend_size, 4 * 3
0172 #ifdef CONFIG_ARM_CPU_SUSPEND
0173 ENTRY(cpu_sa1100_do_suspend)
0174 stmfd sp!, {r4 - r6, lr}
0175 mrc p15, 0, r4, c3, c0, 0 @ domain ID
0176 mrc p15, 0, r5, c13, c0, 0 @ PID
0177 mrc p15, 0, r6, c1, c0, 0 @ control reg
0178 stmia r0, {r4 - r6} @ store cp regs
0179 ldmfd sp!, {r4 - r6, pc}
0180 ENDPROC(cpu_sa1100_do_suspend)
0181
0182 ENTRY(cpu_sa1100_do_resume)
0183 ldmia r0, {r4 - r6} @ load cp regs
0184 mov ip, #0
0185 mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs
0186 mcr p15, 0, ip, c7, c7, 0 @ flush I&D cache
0187 mcr p15, 0, ip, c9, c0, 0 @ invalidate RB
0188 mcr p15, 0, ip, c9, c0, 5 @ allow user space to use RB
0189
0190 mcr p15, 0, r4, c3, c0, 0 @ domain ID
0191 mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
0192 mcr p15, 0, r5, c13, c0, 0 @ PID
0193 mov r0, r6 @ control register
0194 b cpu_resume_mmu
0195 ENDPROC(cpu_sa1100_do_resume)
0196 #endif
0197
0198 .type __sa1100_setup, #function
0199 __sa1100_setup:
0200 mov r0, #0
0201 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
0202 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
0203 #ifdef CONFIG_MMU
0204 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
0205 #endif
0206 adr r5, sa1100_crval
0207 ldmia r5, {r5, r6}
0208 mrc p15, 0, r0, c1, c0 @ get control register v4
0209 bic r0, r0, r5
0210 orr r0, r0, r6
0211 ret lr
0212 .size __sa1100_setup, . - __sa1100_setup
0213
0214
0215
0216
0217
0218
0219
0220 .type sa1100_crval, #object
0221 sa1100_crval:
0222 crval clear=0x00003f3f, mmuset=0x0000313d, ucset=0x00001130
0223
0224 __INITDATA
0225
0226
0227
0228
0229
0230 @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
0231 define_processor_functions sa1100, dabort=v4_early_abort, pabort=legacy_pabort, suspend=1
0232
0233 .section ".rodata"
0234
0235 string cpu_arch_name, "armv4"
0236 string cpu_elf_name, "v4"
0237 string cpu_sa1100_name, "StrongARM-1100"
0238 string cpu_sa1110_name, "StrongARM-1110"
0239
0240 .align
0241
0242 .section ".proc.info.init", "a"
0243
0244 .macro sa1100_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req
0245 .type __\name\()_proc_info,#object
0246 __\name\()_proc_info:
0247 .long \cpu_val
0248 .long \cpu_mask
0249 .long PMD_TYPE_SECT | \
0250 PMD_SECT_BUFFERABLE | \
0251 PMD_SECT_CACHEABLE | \
0252 PMD_SECT_AP_WRITE | \
0253 PMD_SECT_AP_READ
0254 .long PMD_TYPE_SECT | \
0255 PMD_SECT_AP_WRITE | \
0256 PMD_SECT_AP_READ
0257 initfn __sa1100_setup, __\name\()_proc_info
0258 .long cpu_arch_name
0259 .long cpu_elf_name
0260 .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
0261 .long \cpu_name
0262 .long sa1100_processor_functions
0263 .long v4wb_tlb_fns
0264 .long v4_mc_user_fns
0265 .long v4wb_cache_fns
0266 .size __\name\()_proc_info, . - __\name\()_proc_info
0267 .endm
0268
0269 sa1100_proc_info sa1100, 0x4401a110, 0xfffffff0, cpu_sa1100_name
0270 sa1100_proc_info sa1110, 0x6901b110, 0xfffffff0, cpu_sa1110_name