diff options
-rw-r--r-- | arch/arm/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm926.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/proc-v6.S | 7 | ||||
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 26 | ||||
-rw-r--r-- | include/asm-arm/system.h | 43 |
5 files changed, 57 insertions, 24 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 238dd9b6db84..cf2bd4242803 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -354,9 +354,6 @@ static void __init setup_processor(void) | |||
354 | #ifndef CONFIG_ARM_THUMB | 354 | #ifndef CONFIG_ARM_THUMB |
355 | elf_hwcap &= ~HWCAP_THUMB; | 355 | elf_hwcap &= ~HWCAP_THUMB; |
356 | #endif | 356 | #endif |
357 | #ifndef CONFIG_VFP | ||
358 | elf_hwcap &= ~HWCAP_VFP; | ||
359 | #endif | ||
360 | 357 | ||
361 | cpu_proc_init(); | 358 | cpu_proc_init(); |
362 | } | 359 | } |
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 8628ed29a955..080efac9d9ff 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S | |||
@@ -480,7 +480,7 @@ __arm926_proc_info: | |||
480 | b __arm926_setup | 480 | b __arm926_setup |
481 | .long cpu_arch_name | 481 | .long cpu_arch_name |
482 | .long cpu_elf_name | 482 | .long cpu_elf_name |
483 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA | 483 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA |
484 | .long cpu_arm926_name | 484 | .long cpu_arm926_name |
485 | .long arm926_processor_functions | 485 | .long arm926_processor_functions |
486 | .long v4wbi_tlb_fns | 486 | .long v4wbi_tlb_fns |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index b440c8a1d345..c40baf8a47f0 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
@@ -207,11 +207,6 @@ __v6_setup: | |||
207 | #endif | 207 | #endif |
208 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 208 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 |
209 | #endif /* CONFIG_MMU */ | 209 | #endif /* CONFIG_MMU */ |
210 | #ifdef CONFIG_VFP | ||
211 | mrc p15, 0, r0, c1, c0, 2 | ||
212 | orr r0, r0, #(0xf << 20) | ||
213 | mcr p15, 0, r0, c1, c0, 2 @ Enable full access to VFP | ||
214 | #endif | ||
215 | adr r5, v6_crval | 210 | adr r5, v6_crval |
216 | ldmia r5, {r5, r6} | 211 | ldmia r5, {r5, r6} |
217 | mrc p15, 0, r0, c1, c0, 0 @ read control register | 212 | mrc p15, 0, r0, c1, c0, 0 @ read control register |
@@ -273,7 +268,7 @@ __v6_proc_info: | |||
273 | b __v6_setup | 268 | b __v6_setup |
274 | .long cpu_arch_name | 269 | .long cpu_arch_name |
275 | .long cpu_elf_name | 270 | .long cpu_elf_name |
276 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA | 271 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA |
277 | .long cpu_v6_name | 272 | .long cpu_v6_name |
278 | .long v6_processor_functions | 273 | .long v6_processor_functions |
279 | .long v6wbi_tlb_fns | 274 | .long v6wbi_tlb_fns |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index f08eafbddcc1..e26cc1f59948 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -263,13 +263,24 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
263 | if (exceptions) | 263 | if (exceptions) |
264 | vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); | 264 | vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); |
265 | } | 265 | } |
266 | 266 | ||
267 | /* | 267 | /* |
268 | * VFP support code initialisation. | 268 | * VFP support code initialisation. |
269 | */ | 269 | */ |
270 | static int __init vfp_init(void) | 270 | static int __init vfp_init(void) |
271 | { | 271 | { |
272 | unsigned int vfpsid; | 272 | unsigned int vfpsid; |
273 | unsigned int cpu_arch = cpu_architecture(); | ||
274 | u32 access = 0; | ||
275 | |||
276 | if (cpu_arch >= CPU_ARCH_ARMv6) { | ||
277 | access = get_copro_access(); | ||
278 | |||
279 | /* | ||
280 | * Enable full access to VFP (cp10 and cp11) | ||
281 | */ | ||
282 | set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11)); | ||
283 | } | ||
273 | 284 | ||
274 | /* | 285 | /* |
275 | * First check that there is a VFP that we can use. | 286 | * First check that there is a VFP that we can use. |
@@ -281,6 +292,12 @@ static int __init vfp_init(void) | |||
281 | printk(KERN_INFO "VFP support v0.3: "); | 292 | printk(KERN_INFO "VFP support v0.3: "); |
282 | if (VFP_arch) { | 293 | if (VFP_arch) { |
283 | printk("not present\n"); | 294 | printk("not present\n"); |
295 | |||
296 | /* | ||
297 | * Restore the copro access register. | ||
298 | */ | ||
299 | if (cpu_arch >= CPU_ARCH_ARMv6) | ||
300 | set_copro_access(access); | ||
284 | } else if (vfpsid & FPSID_NODOUBLE) { | 301 | } else if (vfpsid & FPSID_NODOUBLE) { |
285 | printk("no double precision support\n"); | 302 | printk("no double precision support\n"); |
286 | } else { | 303 | } else { |
@@ -291,9 +308,16 @@ static int __init vfp_init(void) | |||
291 | (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, | 308 | (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, |
292 | (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, | 309 | (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, |
293 | (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); | 310 | (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); |
311 | |||
294 | vfp_vector = vfp_support_entry; | 312 | vfp_vector = vfp_support_entry; |
295 | 313 | ||
296 | thread_register_notifier(&vfp_notifier_block); | 314 | thread_register_notifier(&vfp_notifier_block); |
315 | |||
316 | /* | ||
317 | * We detected VFP, and the support code is | ||
318 | * in place; report VFP support to userspace. | ||
319 | */ | ||
320 | elf_hwcap |= HWCAP_VFP; | ||
297 | } | 321 | } |
298 | return 0; | 322 | return 0; |
299 | } | 323 | } |
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index f05fbe31576c..f60faccf01fa 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h | |||
@@ -139,19 +139,36 @@ static inline int cpu_is_xsc3(void) | |||
139 | #define cpu_is_xscale() 1 | 139 | #define cpu_is_xscale() 1 |
140 | #endif | 140 | #endif |
141 | 141 | ||
142 | #define set_cr(x) \ | 142 | static inline unsigned int get_cr(void) |
143 | __asm__ __volatile__( \ | 143 | { |
144 | "mcr p15, 0, %0, c1, c0, 0 @ set CR" \ | 144 | unsigned int val; |
145 | : : "r" (x) : "cc") | 145 | asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); |
146 | 146 | return val; | |
147 | #define get_cr() \ | 147 | } |
148 | ({ \ | 148 | |
149 | unsigned int __val; \ | 149 | static inline void set_cr(unsigned int val) |
150 | __asm__ __volatile__( \ | 150 | { |
151 | "mrc p15, 0, %0, c1, c0, 0 @ get CR" \ | 151 | asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" |
152 | : "=r" (__val) : : "cc"); \ | 152 | : : "r" (val) : "cc"); |
153 | __val; \ | 153 | } |
154 | }) | 154 | |
155 | #define CPACC_FULL(n) (3 << (n * 2)) | ||
156 | #define CPACC_SVC(n) (1 << (n * 2)) | ||
157 | #define CPACC_DISABLE(n) (0 << (n * 2)) | ||
158 | |||
159 | static inline unsigned int get_copro_access(void) | ||
160 | { | ||
161 | unsigned int val; | ||
162 | asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access" | ||
163 | : "=r" (val) : : "cc"); | ||
164 | return val; | ||
165 | } | ||
166 | |||
167 | static inline void set_copro_access(unsigned int val) | ||
168 | { | ||
169 | asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access" | ||
170 | : : "r" (val) : "cc"); | ||
171 | } | ||
155 | 172 | ||
156 | extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ | 173 | extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ |
157 | extern unsigned long cr_alignment; /* defined in entry-armv.S */ | 174 | extern unsigned long cr_alignment; /* defined in entry-armv.S */ |