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