[PATCH v4 2/2] ARM PJ4B: Add support for errata 4742
Nicolas Pitre
nico at fluxnic.net
Fri Jun 7 22:09:09 EDT 2013
On Fri, 7 Jun 2013, Gregory CLEMENT wrote:
> 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 at free-electrons.com>
Acked-by: Nicolas Pitre <nico at linaro.org>
> ---
> arch/arm/Kconfig | 13 +++++++++++++
> arch/arm/include/asm/glue-proc.h | 9 +++++++++
> arch/arm/mm/proc-macros.S | 5 +++++
> arch/arm/mm/proc-v7.S | 30 +++++++++++++++++++++++++++---
> 4 files changed, 54 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 49d993c..95cbe9d 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1087,6 +1087,19 @@ if !MMU
> source "arch/arm/Kconfig-nommu"
> endif
>
> +config PJ4B_ERRATA_4742
> + bool "PJ4B Errata 4742: IDLE Wake Up Commands can Cause the CPU Core to Cease Operation"
> + depends on CPU_PJ4B && MACH_ARMADA_370
> + help
> + 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.
> + Workaround:
> + The software must insert either a Data Synchronization Barrier (DSB)
> + or Data Memory Barrier (DMB) command immediately after the WFI/WFE
> + instruction
> +
> config ARM_ERRATA_326103
> bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory"
> depends on CPU_V6
> diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
> index ac1dd54..8017e94 100644
> --- a/arch/arm/include/asm/glue-proc.h
> +++ b/arch/arm/include/asm/glue-proc.h
> @@ -230,6 +230,15 @@
> # endif
> #endif
>
> +#ifdef CONFIG_CPU_PJ4B
> +# ifdef CPU_NAME
> +# undef MULTI_CPU
> +# define MULTI_CPU
> +# else
> +# define CPU_NAME cpu_pj4b
> +# endif
> +#endif
> +
> #ifndef MULTI_CPU
> #define cpu_proc_init __glue(CPU_NAME,_proc_init)
> #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 f9a0aa7..e3c48a3 100644
> --- a/arch/arm/mm/proc-macros.S
> +++ b/arch/arm/mm/proc-macros.S
> @@ -333,3 +333,8 @@ ENTRY(\name\()_tlb_fns)
> .endif
> .size \name\()_tlb_fns, . - \name\()_tlb_fns
> .endm
> +
> +.macro globl_equ x, y
> + .globl \x
> + .equ \x, \y
> +.endm
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index fe3a9d3..95d463e 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -342,6 +342,29 @@ __v7_setup:
> mov pc, lr @ return to head.S:__ret
> ENDPROC(__v7_setup)
>
> +#ifdef CONFIG_CPU_PJ4B
> + globl_equ cpu_pj4b_switch_mm, cpu_v7_switch_mm
> + globl_equ cpu_pj4b_set_pte_ext, cpu_v7_set_pte_ext
> + globl_equ cpu_pj4b_proc_init, cpu_v7_proc_init
> + globl_equ cpu_pj4b_proc_fin, cpu_v7_proc_fin
> + globl_equ cpu_pj4b_reset, cpu_v7_reset
> +#ifdef CONFIG_PJ4B_ERRATA_4742
> +ENTRY(cpu_pj4b_do_idle)
> + dsb @ WFI may enter a low-power mode
> + wfi
> + dsb @barrier
> + mov pc, lr
> +ENDPROC(cpu_pj4b_do_idle)
> +#else
> + globl_equ cpu_pj4b_do_idle, cpu_v7_do_idle
> +#endif
> + globl_equ cpu_pj4b_dcache_clean_area, cpu_v7_dcache_clean_area
> + globl_equ cpu_pj4b_do_suspend, cpu_v7_do_suspend
> + globl_equ cpu_pj4b_do_resume, cpu_v7_do_resume
> + globl_equ cpu_pj4b_suspend_size, cpu_v7_suspend_size
> +
> +#endif
> +
> .align 2
> __v7_setup_stack:
> .space 4 * 11 @ 11 registers
> @@ -350,6 +373,7 @@ __v7_setup_stack:
>
> @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
> define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
> + define_processor_functions pj4b, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
>
> .section ".rodata"
>
> @@ -362,7 +386,7 @@ __v7_setup_stack:
> /*
> * Standard v7 proc info content
> */
> -.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0
> +.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0, proc_fns = v7_processor_functions
> ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
> PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags)
> ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
> @@ -375,7 +399,7 @@ __v7_setup_stack:
> .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \
> HWCAP_EDSP | HWCAP_TLS | \hwcaps
> .long cpu_v7_name
> - .long v7_processor_functions
> + .long \proc_fns
> .long v7wbi_tlb_fns
> .long v6_user_fns
> .long v7_cache_fns
> @@ -411,7 +435,7 @@ __v7_ca9mp_proc_info:
> __v7_pj4b_proc_info:
> .long 0x560f5800
> .long 0xff0fff00
> - __v7_proc __v7_pj4b_setup
> + __v7_proc __v7_pj4b_setup, proc_fns = pj4b_processor_functions
> .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info
>
> /*
> --
> 1.8.1.2
>
More information about the linux-arm-kernel
mailing list