aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorGregory CLEMENT <gregory.clement@free-electrons.com>2013-06-23 05:17:11 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-06-24 09:28:46 -0400
commit3e0a07f8c401bb43e0f964c5f1285b2cb2028645 (patch)
tree8d25c87e417d999d33f621cf74371df5d6751c66 /arch/arm
parent63384fd0b1509acf522a8a8fcede09087eedb7df (diff)
ARM: 7773/1: PJ4B: Add support for errata 4742
This commit fixes the regression on Armada 370 (the kernal hang during boot) introduced by the commit: "ARM: 7691/1: mm: kill unused TLB_CAN_READ_FROM_L1_CACHE and use ALT_SMP instead". When coming out of either a Wait for Interrupt (WFI) or a Wait for Event (WFE) IDLE states, a specific timing sensitivity exists between the retiring WFI/WFE instructions and the newly issued subsequent instructions. This sensitivity can result in a CPU hang scenario. The workaround is to insert either a Data Synchronization Barrier (DSB) or Data Memory Barrier (DMB) command immediately after the WFI/WFE instruction. This commit was based on the work of Lior Amsalem, but heavily modified to apply the errata fix dynamically according to the processor type thanks to the suggestions of Russell King and Nicolas Pitre. Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Reviewed-by: Will Deacon <will.deacon@arm.com> Acked-by: Nicolas Pitre <nico@linaro.org> Tested-by: Willy Tarreau <w@1wt.eu> Cc: <stable@vger.kernel.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig14
-rw-r--r--arch/arm/include/asm/glue-proc.h9
-rw-r--r--arch/arm/mm/proc-macros.S5
-rw-r--r--arch/arm/mm/proc-v7.S34
4 files changed, 59 insertions, 3 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2651b1da1c56..136f263ed47b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1087,6 +1087,20 @@ if !MMU
1087source "arch/arm/Kconfig-nommu" 1087source "arch/arm/Kconfig-nommu"
1088endif 1088endif
1089 1089
1090config PJ4B_ERRATA_4742
1091 bool "PJ4B Errata 4742: IDLE Wake Up Commands can Cause the CPU Core to Cease Operation"
1092 depends on CPU_PJ4B && MACH_ARMADA_370
1093 default y
1094 help
1095 When coming out of either a Wait for Interrupt (WFI) or a Wait for
1096 Event (WFE) IDLE states, a specific timing sensitivity exists between
1097 the retiring WFI/WFE instructions and the newly issued subsequent
1098 instructions. This sensitivity can result in a CPU hang scenario.
1099 Workaround:
1100 The software must insert either a Data Synchronization Barrier (DSB)
1101 or Data Memory Barrier (DMB) command immediately after the WFI/WFE
1102 instruction
1103
1090config ARM_ERRATA_326103 1104config ARM_ERRATA_326103
1091 bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory" 1105 bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory"
1092 depends on CPU_V6 1106 depends on CPU_V6
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
index ac1dd54724b6..8017e94acc5e 100644
--- a/arch/arm/include/asm/glue-proc.h
+++ b/arch/arm/include/asm/glue-proc.h
@@ -230,6 +230,15 @@
230# endif 230# endif
231#endif 231#endif
232 232
233#ifdef CONFIG_CPU_PJ4B
234# ifdef CPU_NAME
235# undef MULTI_CPU
236# define MULTI_CPU
237# else
238# define CPU_NAME cpu_pj4b
239# endif
240#endif
241
233#ifndef MULTI_CPU 242#ifndef MULTI_CPU
234#define cpu_proc_init __glue(CPU_NAME,_proc_init) 243#define cpu_proc_init __glue(CPU_NAME,_proc_init)
235#define cpu_proc_fin __glue(CPU_NAME,_proc_fin) 244#define cpu_proc_fin __glue(CPU_NAME,_proc_fin)
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index f9a0aa725ea9..e3c48a3fe063 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -333,3 +333,8 @@ ENTRY(\name\()_tlb_fns)
333 .endif 333 .endif
334 .size \name\()_tlb_fns, . - \name\()_tlb_fns 334 .size \name\()_tlb_fns, . - \name\()_tlb_fns
335.endm 335.endm
336
337.macro globl_equ x, y
338 .globl \x
339 .equ \x, \y
340.endm
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 4c8c9c10a388..e35fec34453e 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -140,6 +140,29 @@ ENTRY(cpu_v7_do_resume)
140ENDPROC(cpu_v7_do_resume) 140ENDPROC(cpu_v7_do_resume)
141#endif 141#endif
142 142
143#ifdef CONFIG_CPU_PJ4B
144 globl_equ cpu_pj4b_switch_mm, cpu_v7_switch_mm
145 globl_equ cpu_pj4b_set_pte_ext, cpu_v7_set_pte_ext
146 globl_equ cpu_pj4b_proc_init, cpu_v7_proc_init
147 globl_equ cpu_pj4b_proc_fin, cpu_v7_proc_fin
148 globl_equ cpu_pj4b_reset, cpu_v7_reset
149#ifdef CONFIG_PJ4B_ERRATA_4742
150ENTRY(cpu_pj4b_do_idle)
151 dsb @ WFI may enter a low-power mode
152 wfi
153 dsb @barrier
154 mov pc, lr
155ENDPROC(cpu_pj4b_do_idle)
156#else
157 globl_equ cpu_pj4b_do_idle, cpu_v7_do_idle
158#endif
159 globl_equ cpu_pj4b_dcache_clean_area, cpu_v7_dcache_clean_area
160 globl_equ cpu_pj4b_do_suspend, cpu_v7_do_suspend
161 globl_equ cpu_pj4b_do_resume, cpu_v7_do_resume
162 globl_equ cpu_pj4b_suspend_size, cpu_v7_suspend_size
163
164#endif
165
143 __CPUINIT 166 __CPUINIT
144 167
145/* 168/*
@@ -350,6 +373,9 @@ __v7_setup_stack:
350 373
351 @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) 374 @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
352 define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 375 define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
376#ifdef CONFIG_CPU_PJ4B
377 define_processor_functions pj4b, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
378#endif
353 379
354 .section ".rodata" 380 .section ".rodata"
355 381
@@ -362,7 +388,7 @@ __v7_setup_stack:
362 /* 388 /*
363 * Standard v7 proc info content 389 * Standard v7 proc info content
364 */ 390 */
365.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0 391.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0, proc_fns = v7_processor_functions
366 ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ 392 ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
367 PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags) 393 PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags)
368 ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ 394 ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
@@ -375,7 +401,7 @@ __v7_setup_stack:
375 .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \ 401 .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \
376 HWCAP_EDSP | HWCAP_TLS | \hwcaps 402 HWCAP_EDSP | HWCAP_TLS | \hwcaps
377 .long cpu_v7_name 403 .long cpu_v7_name
378 .long v7_processor_functions 404 .long \proc_fns
379 .long v7wbi_tlb_fns 405 .long v7wbi_tlb_fns
380 .long v6_user_fns 406 .long v6_user_fns
381 .long v7_cache_fns 407 .long v7_cache_fns
@@ -407,12 +433,14 @@ __v7_ca9mp_proc_info:
407 /* 433 /*
408 * Marvell PJ4B processor. 434 * Marvell PJ4B processor.
409 */ 435 */
436#ifdef CONFIG_CPU_PJ4B
410 .type __v7_pj4b_proc_info, #object 437 .type __v7_pj4b_proc_info, #object
411__v7_pj4b_proc_info: 438__v7_pj4b_proc_info:
412 .long 0x560f5800 439 .long 0x560f5800
413 .long 0xff0fff00 440 .long 0xff0fff00
414 __v7_proc __v7_pj4b_setup 441 __v7_proc __v7_pj4b_setup, proc_fns = pj4b_processor_functions
415 .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info 442 .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info
443#endif
416 444
417 /* 445 /*
418 * ARM Ltd. Cortex A7 processor. 446 * ARM Ltd. Cortex A7 processor.