From: Wang Dongsheng <dongsheng.w...@freescale.com>

low power boot means u-boot will put non-boot cpus into a low power
status. Non-boot cpus don't need any more spin wait. e500, e500v2 will
going to DOZE status. e500mc, e5500, e6500 will going to PW10 state.

e500/e500v2 will be kicked up by MPIC-IPI, e500mc later will be kicked up
by doorbell.

This feature tested on:
POWER UP TEST:
P1022DS(e500v2),96k times.
P4080(e500mc),  110k times.
T1024(e5500),   83k times.
T4240(e6500),   150k times.

CPU HOTPLUG TEST:
P1022DS(e500v2),1.4 million times.
P4080(e500mc),  1.8 million times.
T1024(e5500),   1.3 million times.
T4240(e6500),   1.1 million times.

Signed-off-by: Wang Dongsheng <dongsheng.w...@freescale.com>
---
*V2*
Add:
    Add Config option to select Boot Method, Boot by SPIN TABLE or Boot By
    LOW POWER.
    The default boot method is SPIN TABLE.

Modify:
    Rebase code to compatible with spin.

Delete:
    Delete e6500rev2 PW20 state.

The default boot method SPIN TABLE has tested on last kernel. The low power boot
method need add a kernel patch to support. Now PPC smp cpu boot, cpu hotplug,
sleep, and deep sleep patches is rebasing for upstream, after ppc smp cpu boot
upstreamed i will commit a kernel patch to complete support low power boot 
method.

diff --git a/arch/powerpc/cpu/mpc85xx/Kconfig b/arch/powerpc/cpu/mpc85xx/Kconfig
index 3e8d0b1..9c81d97 100644
--- a/arch/powerpc/cpu/mpc85xx/Kconfig
+++ b/arch/powerpc/cpu/mpc85xx/Kconfig
@@ -199,3 +199,26 @@ source "board/xes/xpedite550x/Kconfig"
 source "board/Arcturus/ucp1020/Kconfig"
 
 endmenu
+
+menu "mpc85xx CPU Boot Method"
+       depends on MPC85xx
+
+choice
+       prompt "Boot select"
+       default BOOT_BY_SPIN
+
+config BOOT_BY_SPIN
+       bool "Spin boot cpus"
+       help
+         Non-boot cpus will be falled in a spin state when U-boot
+         started up.
+
+config BOOT_BY_LOW_POWER
+       bool "Low power boot cpus"
+       help
+         Non-boot cpus will be falled in a low power state when U-boot
+         started up.
+
+endchoice
+
+endmenu
diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c
index ef08489..fbbc686 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu.c
@@ -284,6 +284,11 @@ int checkcpu (void)
        puts("\n");
 #endif
 
+#if defined(CONFIG_BOOT_BY_SPIN)
+       printf("Boot-Method: SPIN BOOT\n");
+#elif defined(CONFIG_BOOT_BY_LOW_POWER)
+       printf("Boot-Method: LOW POWER BOOT\n");
+#endif
        return 0;
 }
 
diff --git a/arch/powerpc/cpu/mpc85xx/release.S 
b/arch/powerpc/cpu/mpc85xx/release.S
index 0e0daf5..23289a4 100644
--- a/arch/powerpc/cpu/mpc85xx/release.S
+++ b/arch/powerpc/cpu/mpc85xx/release.S
@@ -296,10 +296,15 @@ __secondary_start_page:
        mtspr   SPRN_MAS7,r11
        tlbwe
 
+       li      r6, 0
+
        /*
         * __bootpg_addr has the address of __second_half_boot_page
         * jump there in AS=1 space with cache enabled
         */
+       .align 6
+       .global jump_second_half_boot_page
+jump_second_half_boot_page:
        lis     r13,toreset(__bootpg_addr)@h
        ori     r13,r13,toreset(__bootpg_addr)@l
        lwz     r11,0(r13)
@@ -370,6 +375,9 @@ __second_half_boot_page:
         * };
         * we pad this struct to 64 bytes so each entry is in its own cacheline
         */
+       cmpwi   r6, 1
+       beq     3f
+
        li      r3,0
        li      r8,1
        mfspr   r4,SPRN_PIR
@@ -401,7 +409,64 @@ __second_half_boot_page:
 #endif
        lwz     r4,ENTRY_ADDR_LOWER(r10)
        andi.   r11,r4,1
+#if defined(CONFIG_BOOT_BY_SPIN)
        bne     3b
+#elif defined(CONFIG_BOOT_BY_LOW_POWER)
+       beq     6f
+
+       li      r6, 1
+
+       /* External Interrupt exception. */
+       lis     r7, toreset(jump_second_half_boot_page)@h
+       mtspr   SPRN_IVPR, r7
+       li      r7, toreset(jump_second_half_boot_page)@l
+
+#ifdef CONFIG_E500MC
+       /* e500MC, e5500, e6500 will use doorbell to send ipi signal */
+       mtspr   SPRN_IVOR36, r7
+#endif
+
+       mtspr   SPRN_IVOR4, r7
+
+       isync
+
+#ifdef CONFIG_E500MC
+       li      r7, 0
+       mtspr   SPRN_PIR, r7
+
+       wrteei  1
+       wait
+#else
+       li      r5, 0
+       lis     r5, HID0_DOZE@h
+       mfspr   r7, SPRN_HID0
+       rlwinm  r7, r7, 0, ~(HID0_DOZE | HID0_NAP | HID0_SLEEP)
+       or      r7, r7, r5
+       isync
+       mtspr   SPRN_HID0, r7
+       isync
+
+       mfmsr   r7
+       oris    r7, r7, MSR_WE@h
+       ori     r7, r7, MSR_EE
+       msync
+       mtmsr   r7
+       isync
+5:     bl      5b
+#endif
+
+6:
+       wrteei  0
+#endif
+
+       mfspr   r7, SPRN_EPR
+7:
+       lwz     r7, ENTRY_PIR(r10)
+       andi.   r7, r7, 0xffff
+       bne     8f
+       bl      7b
+
+8:
        isync
 
        /* get the upper bits of the addr */
diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index fdfca90..2d7c356 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -482,6 +482,7 @@
 #define SPRN_GIVOR8    0x1bb   /* Guest Interrupt Vector Offset Register 8 */
 #define SPRN_GIVOR13   0x1bc   /* Guest Interrupt Vector Offset Register 13 */
 #define SPRN_GIVOR14   0x1bd   /* Guest Interrupt Vector Offset Register 14 */
+#define SPRN_EPR       0x2be   /* External Proxy Register */
 
 /* e500 definitions */
 #define SPRN_L1CFG0    0x203   /* L1 Cache Configuration Register 0 */
-- 
2.1.0.27.g96db324

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to