Hi all,

Kernel patch link:
http://patchwork.ozlabs.org/patch/429259/

Regards,
-Dongsheng

> -----Original Message-----
> From: Dongsheng Wang [mailto:dongsheng.w...@freescale.com]
> Sent: Thursday, January 15, 2015 2:05 PM
> To: Sun York-R58495; Wood Scott-B07421; Li Yang-Leo-R58472
> Cc: Jin Zhengxiong-R64188; u-boot@lists.denx.de; Wang Dongsheng-B40534
> Subject: [PATCH] powerpc/fsl: support low power boot for e500 and later
> 
> 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, e6500rev1 will going to PW10 state.
> e6500rev2 will going to PW20 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>
> 
> diff --git a/arch/powerpc/cpu/mpc85xx/release.S
> b/arch/powerpc/cpu/mpc85xx/release.S
> index a2c0ad4..a97a1b6 100644
> --- a/arch/powerpc/cpu/mpc85xx/release.S
> +++ b/arch/powerpc/cpu/mpc85xx/release.S
> @@ -297,10 +297,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_half_boot_page
> +jump_half_boot_page:
>       lis     r13,toreset(__bootpg_addr)@h
>       ori     r13,r13,toreset(__bootpg_addr)@l
>       lwz     r11,0(r13)
> @@ -371,6 +376,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
> @@ -402,7 +410,132 @@ __second_half_boot_page:
>  #endif
>       lwz     r4,ENTRY_ADDR_LOWER(r10)
>       andi.   r11,r4,1
> -     bne     3b
> +     beq     6f
> +
> +     li      r6, 0
> +     addi    r6, r6, 1
> +
> +     /* External Interrupt exception. */
> +     lis     r7, toreset(jump_half_boot_page)@h
> +     mtspr   SPRN_IVPR, r7
> +     li      r7, toreset(jump_half_boot_page)@l
> +
> +#ifdef       CONFIG_E500MC
> +     /* e500MC, e5500, e6500 will use doorbell to send ipi signal */
> +     mtspr   SPRN_IVOR36, r7
> +#endif
> +
> +     /*
> +      * For e500mc later:
> +      * EE will open in low power state, IVOR4 make sure we can ACK
> +      * trash interrupt and keep we can loop in wait state again until
> +      * the desired interrupt coming.
> +      *
> +      * e500, e500v2:
> +      * Kernel will use MPCI to send ipi signal, so we must set IVOR4.
> +      */
> +     mtspr   SPRN_IVOR4, r7
> +
> +     isync
> +
> +#ifdef       CONFIG_E500MC
> +     /* PW20 & AltiVec idle feature only exists for E6500 */
> +     mfspr   r0, SPRN_PVR
> +     rlwinm  r11, r0, 16, 16, 31
> +     lis     r12, 0
> +     ori     r12, r12, PVR_VER_E6500@l
> +     cmpw    r11, r12
> +     bne     5f
> +
> +     /* Fix erratum, e6500 rev1 does not support PW20 & AltiVec idle */
> +     rlwinm  r11, r0, 0, 16, 31
> +     cmpwi   r11, 0x20
> +     blt     5f
> +
> +#define PW20_WAIT_IDLE_BIT   50 /* 1ms, TB frequency is 41.66MHZ */
> +     /* Core Enter PW20 State */
> +     mfspr   r7, SPRN_PWRMGTCR0
> +     /* Set PW20_WAIT bit, enable pw20 state*/
> +     ori     r7, r7, PWRMGTCR0_PW20_WAIT
> +     li      r9, PW20_WAIT_IDLE_BIT
> +     /* Set Automatic PW20 Core Idle Count */
> +     rlwimi  r7, r9, PWRMGTCR0_PW20_ENT_SHIFT, PWRMGTCR0_PW20_ENT
> +     mtspr   SPRN_PWRMGTCR0, r7
> +
> +#define AV_WAIT_IDLE_BIT     50 /* 1ms, TB frequency is 41.66MHZ */
> +     /* Let Altivec Enter Idle State */
> +     mfspr   r7, SPRN_PWRMGTCR0
> +     /* Enable Altivec Idle */
> +     oris    r7, r7, PWRMGTCR0_AV_IDLE_PD_EN@h
> +     li      r9, AV_WAIT_IDLE_BIT
> +     /* Set Automatic AltiVec Idle Count */
> +     rlwimi  r7, r9, PWRMGTCR0_AV_IDLE_CNT_SHIFT, PWRMGTCR0_AV_IDLE_CNT
> +     mtspr   SPRN_PWRMGTCR0, r7
> +
> +5:
> +     /*
> +      * Set all of cpu PIR-ID is 0, wait kernel send doorbell or MPIC-IPI
> +      * signal.
> +      *
> +      * When kernel kick one of cpus, all cpus will be wakenup. To make
> +      * sure that only the target cpu is effected, other cpus (by checking
> +      * spin_table->addr_l) should go back to low power state.
> +      *
> +      * U-boot has renumber the cpu PIR Why we need to set all of PIR to
> +      * the same value?
> +      * A: Before kernel kicking cpu, the doorbell message was not configured
> +      * for target cpu(cpu_messages->data). If we try to send a
> +      * non-configured message to target cpu, it cannot correctly receive
> +      * doorbell interrput. So SET ALL OF CPU'S PIR to the same value to
> +      * let all cpus catch the interrupt.
> +      *
> +      * Why set PIR to zero?
> +      * A: U-boot cannot know how many cpus will be kicked up(Kernel allow us
> +      * to configure NR_CPUS) and IPI is a per_cpu variable, u-boot cannot
> +      * set a appropriate PIR for every cpu, but the boot cpu(CPU0) always be
> +      * there. So set PIR is zero as a default PIR ID for each CPUs.
> +      */
> +
> +     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
> +
> +     /*
> +      * If proxy mode enable in MPIC, Read EPR to ACK INTERRUPT
> +      * Or proxy mode disable, Kernel will read MPIC to ACK INTERRUPT.
> +      */
> +     mfspr   r7, SPRN_EPR
> +
> +     /* Wait EOI finish */
> +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 2ed51b1..4d49317 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 */
> @@ -565,6 +566,13 @@
>  #define SPRN_BBTAR   0x202   /* Branch Buffer Target Address Register */
>  #define SPRN_PID1    0x279   /* Process ID Register 1 */
>  #define SPRN_PID2    0x27a   /* Process ID Register 2 */
> +#define SPRN_PWRMGTCR0  0x3fb        /* Power management control register 0 
> */
> +#define   PWRMGTCR0_PW20_WAIT                (1 << 14) /* PW20 state enable 
> bit */
> +#define   PWRMGTCR0_PW20_ENT_SHIFT   8
> +#define   PWRMGTCR0_PW20_ENT         0x3f00
> +#define   PWRMGTCR0_AV_IDLE_PD_EN    (1 << 22) /* Altivec idle enable */
> +#define   PWRMGTCR0_AV_IDLE_CNT_SHIFT        16
> +#define   PWRMGTCR0_AV_IDLE_CNT              0x3f0000
>  #define SPRN_MCSR    0x23c   /* Machine Check Syndrome register */
>  #define SPRN_MCAR    0x23d   /* Machine Check Address register */
>  #define MCSR_MCS     0x80000000      /* Machine Check Summary */
> --
> 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