Commit 087bb28329f3ccda4e50cb4cf297542d7e773e20

Authored by Shawn Guo
1 parent 0e574461c4

ARM: imx: replicate the diagnostic register of boot cpu into secondary cores

The diagnostic register holds the errata bits.  Mostly bootloader
does not bring up secondary cores, so that when errata bits are set
in bootloader, they are set only for boot cpu.  But on a SMP
configuration, it should be equally done on every single core.
Set up the diagnostic register for secondary cores by replicating
the register from boot cpu.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>

Showing 2 changed files with 26 additions and 0 deletions Side-by-side Diff

arch/arm/mach-imx/headsmp.S
... ... @@ -18,8 +18,20 @@
18 18 .section ".text.head", "ax"
19 19  
20 20 #ifdef CONFIG_SMP
  21 +diag_reg_offset:
  22 + .word g_diag_reg - .
  23 +
  24 + .macro set_diag_reg
  25 + adr r0, diag_reg_offset
  26 + ldr r1, [r0]
  27 + add r1, r1, r0 @ r1 = physical &g_diag_reg
  28 + ldr r0, [r1]
  29 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
  30 + .endm
  31 +
21 32 ENTRY(v7_secondary_startup)
22 33 bl v7_invalidate_l1
  34 + set_diag_reg
23 35 b secondary_startup
24 36 ENDPROC(v7_secondary_startup)
25 37 #endif
arch/arm/mach-imx/platsmp.c
... ... @@ -12,6 +12,7 @@
12 12  
13 13 #include <linux/init.h>
14 14 #include <linux/smp.h>
  15 +#include <asm/cacheflush.h>
15 16 #include <asm/page.h>
16 17 #include <asm/smp_scu.h>
17 18 #include <asm/mach/map.h>
... ... @@ -21,6 +22,7 @@
21 22  
22 23 #define SCU_STANDBY_ENABLE (1 << 5)
23 24  
  25 +u32 g_diag_reg;
24 26 static void __iomem *scu_base;
25 27  
26 28 static struct map_desc scu_io_desc __initdata = {
... ... @@ -80,6 +82,18 @@
80 82 static void __init imx_smp_prepare_cpus(unsigned int max_cpus)
81 83 {
82 84 imx_smp_prepare();
  85 +
  86 + /*
  87 + * The diagnostic register holds the errata bits. Mostly bootloader
  88 + * does not bring up secondary cores, so that when errata bits are set
  89 + * in bootloader, they are set only for boot cpu. But on a SMP
  90 + * configuration, it should be equally done on every single core.
  91 + * Read the register from boot cpu here, and will replicate it into
  92 + * secondary cores when booting them.
  93 + */
  94 + asm("mrc p15, 0, %0, c15, c0, 1" : "=r" (g_diag_reg) : : "cc");
  95 + __cpuc_flush_dcache_area(&g_diag_reg, sizeof(g_diag_reg));
  96 + outer_clean_range(__pa(&g_diag_reg), __pa(&g_diag_reg + 1));
83 97 }
84 98  
85 99 struct smp_operations imx_smp_ops __initdata = {