ARM: UniPhier: optimize kicking secondary CPUs code
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Sun, 22 Mar 2015 15:07:31 +0000 (00:07 +0900)
committerMasahiro Yamada <yamada.masahiro@socionext.com>
Mon, 23 Mar 2015 15:15:55 +0000 (00:15 +0900)
Currently, the secondary CPU(s) are kicked three times:
Boot ROM ---(kick)--> SPL ---(kick)--> U-boot ---(kick)--> Linux.
It makes the boot sequence very complicated.

This commit merges the first and the second kicks, so the secondary
CPU(s) can directly jump from SPL to Linux.
arch/arm/mach-uniphier/smp.S is no longer necessary.

Linux boot test passed.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
arch/arm/mach-uniphier/Makefile
arch/arm/mach-uniphier/cache_uniphier.c
arch/arm/mach-uniphier/lowlevel_init.S
arch/arm/mach-uniphier/smp.S [deleted file]

index f191aa3d76df8257f5cbad85929b568d41144299..24591d6ee56faacce99d7de469bcc2b4f1648d88 100644 (file)
@@ -22,7 +22,6 @@ obj-$(CONFIG_BOARD_EARLY_INIT_R) += board_early_init_r.o
 obj-$(CONFIG_BOARD_LATE_INIT) += board_late_init.o
 obj-y += reset.o
 obj-y += cache_uniphier.o
-obj-$(CONFIG_UNIPHIER_SMP) += smp.o
 obj-$(CONFIG_CMD_PINMON) += cmd_pinmon.o
 obj-$(CONFIG_CMD_DDRPHY_DUMP) += cmd_ddrphy.o
 
index 52f3c7c7a65e0a300e1221adf13a9fb85510b892..4bf01bce3ea5200e80f0e150b1ef354ad28b0851 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2012-2014 Panasonic Corporation
- *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ * Copyright (C) 2015      Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -119,20 +120,10 @@ void v7_outer_cache_disable(void)
        writel(tmp, SSCC);
 }
 
-void wakeup_secondary(void);
-
 void enable_caches(void)
 {
        uint32_t reg;
 
-#ifdef CONFIG_UNIPHIER_SMP
-       /*
-        * The secondary CPU must move to DDR,
-        * before L2 disable.
-        * On SPL, the Page Table is located on the L2.
-        */
-       wakeup_secondary();
-#endif
        /*
         * UniPhier SoCs must use L2 cache for init stack pointer.
         * We disable L2 and L1 in this order.
index 4a23ea4d560d2d965017835d9eb91cb1bb3a66f5..825b16076245be7fdb1f74c55a3ea6da4c3929b1 100644 (file)
@@ -48,6 +48,25 @@ ENTRY(lowlevel_init)
        bl      enable_mmu
 
 #ifdef CONFIG_UNIPHIER_SMP
+secondary_startup:
+       /*
+        * Entry point for secondary CPUs
+        *
+        * The Boot ROM has already enabled MMU for the secondary CPUs as well
+        * as for the primary one.  The MMU table embedded in the Boot ROM
+        * prohibits the DRAM access, so it is impossible to bring the
+        * secondary CPUs into DRAM directly.  They must jump here into SPL,
+        * which is run on L2 cache.
+        *
+        * Boot Sequence
+        *  [primary CPU]                    [secondary CPUs]
+        *  start from Boot ROM             start from Boot ROM
+        *     jump to SPL                    sleep in Boot ROM
+        *  kick secondaries   ---(sev)--->    jump to SPL
+        *  jump to U-Boot main               sleep in SPL
+        *  jump to Linux
+        *  kick secondaries   ---(sev)--->    jump to Linux
+        */
        /*
         * ACTLR (Auxiliary Control Register) for Cortex-A9
         * bit[9]  Parity on
@@ -68,17 +87,28 @@ ENTRY(lowlevel_init)
        and     r0, r0, #0x3
        cmp     r0, #0x0
        beq     primary_cpu
-       ldr     r1, =ROM_BOOT_ROMRSV2
+       /* only for secondary CPUs */
+       ldr     r1, =ROM_BOOT_ROMRSV2   @ The last data access to L2 cache
+       mrc     p15, 0, r0, c1, c0, 0   @ SCTLR (System Control Register)
+       orr     r0, r0, #CR_I           @ Enable ICache
+       bic     r0, r0, #(CR_C | CR_M)  @ MMU and Dcache must be disabled
+       mcr     p15, 0, r0, c1, c0, 0   @ before jumping to Linux
        mov     r0, #0
        str     r0, [r1]
-0:     wfe
-       ldr     r0, [r1]
+       b       1f
+       /*
+        * L2 cache is shared among all the CPUs and it might be disabled by
+        * the primary one.  Before that, the following 5 lines must be cached
+        * on the Icaches of the secondary CPUs.
+        */
+0:     wfe                             @ kicked by Linux
+1:     ldr     r0, [r1]
        cmp     r0, #0
-       beq     0b
-       bx      r0                      @ r0: entry point of U-Boot main for the secondary CPU
+       bxne    r0                      @ r0: Linux entry for secondary CPUs
+       b       0b
 primary_cpu:
        ldr     r1, =ROM_BOOT_ROMRSV2
-       ldr     r0, =_start             @ entry for the secondary CPU
+       ldr     r0, =secondary_startup
        str     r0, [r1]
        ldr     r0, [r1]                @ make sure str is complete before sev
        sev                             @ kick the secondary CPU
diff --git a/arch/arm/mach-uniphier/smp.S b/arch/arm/mach-uniphier/smp.S
deleted file mode 100644 (file)
index 18e3a9d..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2013 Panasonic Corporation
- *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <config.h>
-#include <linux/linkage.h>
-#include <asm/system.h>
-#include <mach/led.h>
-#include <mach/sbc-regs.h>
-
-/* Entry point of U-Boot main program for the secondary CPU */
-LENTRY(secondary_entry)
-       mrc     p15, 0, r0, c1, c0, 0   @ SCTLR (System Contrl Register)
-       bic     r0, r0, #(CR_C | CR_M)  @ MMU and Dcache disable
-       mcr     p15, 0, r0, c1, c0, 0
-       mcr     p15, 0, r0, c8, c7, 0   @ invalidate TLBs
-       mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
-       dsb
-       led_write(C,0,,)
-       ldr     r1, =ROM_BOOT_ROMRSV2
-       mov     r0, #0
-       str     r0, [r1]
-0:     wfe
-       ldr     r4, [r1]                @ r4: entry point for secondary CPUs
-       cmp     r4, #0
-       beq     0b
-       led_write(C, P, U, 1)
-       bx      r4                      @ secondary CPUs jump to linux
-ENDPROC(secondary_entry)
-
-ENTRY(wakeup_secondary)
-       ldr     r1, =ROM_BOOT_ROMRSV2
-0:     ldr     r0, [r1]
-       cmp     r0, #0
-       bne     0b
-
-       /* set entry address and send event to the secondary CPU */
-       ldr     r0, =secondary_entry
-       str     r0, [r1]
-       ldr     r0, [r1]        @ make sure store is complete
-       mov     r0, #0x100
-0:     subs    r0, r0, #1      @ I don't know the reason, but without this wait
-       bne     0b              @ fails to wake up the secondary CPU
-       sev
-
-       /* wait until the secondary CPU reach to secondary_entry */
-0:     ldr     r0, [r1]
-       cmp     r0, #0
-       bne     0b
-       bx      lr
-ENDPROC(wakeup_secondary)