Re: [PATCH] powerpc/85xx: add sleep and deep sleep support
On Sat, Aug 1, 2015 at 10:57 AM, Scott Wood wrote: On Fri, 2015-07-24 at 20:46 +0800, Chenhui Zhao wrote: +static void mpc85xx_pmc_set_wake(struct device *dev, void *enable) { int ret; + u32 value[2]; + + if (!device_may_wakeup(dev)) + return; + + if (!pmc_regs) { + dev_err(dev, "%s: PMC is unavailable\n", __func__); + return; + } + + ret = of_property_read_u32_array(dev->of_node, "sleep", value, 2); This will crash on any device without an of_node. Add this before this line: if (!dev->of_node) return; + if (ret) { + dev_dbg(dev, "%s: Can not find the \"sleep\" property.\n", + __func__); + return; + } + + if (*(int *)enable) + pmc_pmcdr_mask &= ~value[1]; + else + pmc_pmcdr_mask |= value[1]; + + if ((value[1] & 0xe0) && (pmc_flag & PMC_LOSSLESS)) + pmc_powmgtcsr = POWMGTCSR_LOSSLESS; +} What is 0xe0? -Scott This is a mask value for the register PMCDR, which includes all bits corresponding to eTSEC. Will use a macro instead. -Chenhui -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] powerpc/85xx: add sleep and deep sleep support
On Sat, Aug 1, 2015 at 10:57 AM, Scott Wood scottw...@freescale.com wrote: On Fri, 2015-07-24 at 20:46 +0800, Chenhui Zhao wrote: +static void mpc85xx_pmc_set_wake(struct device *dev, void *enable) { int ret; + u32 value[2]; + + if (!device_may_wakeup(dev)) + return; + + if (!pmc_regs) { + dev_err(dev, %s: PMC is unavailable\n, __func__); + return; + } + + ret = of_property_read_u32_array(dev-of_node, sleep, value, 2); This will crash on any device without an of_node. Add this before this line: if (!dev-of_node) return; + if (ret) { + dev_dbg(dev, %s: Can not find the \sleep\ property.\n, + __func__); + return; + } + + if (*(int *)enable) + pmc_pmcdr_mask = ~value[1]; + else + pmc_pmcdr_mask |= value[1]; + + if ((value[1] 0xe0) (pmc_flag PMC_LOSSLESS)) + pmc_powmgtcsr = POWMGTCSR_LOSSLESS; +} What is 0xe0? -Scott This is a mask value for the register PMCDR, which includes all bits corresponding to eTSEC. Will use a macro instead. -Chenhui -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] powerpc/85xx: add sleep and deep sleep support
On Fri, 2015-07-24 at 20:46 +0800, Chenhui Zhao wrote: > +static void mpc85xx_pmc_set_wake(struct device *dev, void *enable) > { > int ret; > + u32 value[2]; > + > + if (!device_may_wakeup(dev)) > + return; > + > + if (!pmc_regs) { > + dev_err(dev, "%s: PMC is unavailable\n", __func__); > + return; > + } > + > + ret = of_property_read_u32_array(dev->of_node, "sleep", value, 2); This will crash on any device without an of_node. > + if (ret) { > + dev_dbg(dev, "%s: Can not find the \"sleep\" property.\n", > + __func__); > + return; > + } > + > + if (*(int *)enable) > + pmc_pmcdr_mask &= ~value[1]; > + else > + pmc_pmcdr_mask |= value[1]; > + > + if ((value[1] & 0xe0) && (pmc_flag & PMC_LOSSLESS)) > + pmc_powmgtcsr = POWMGTCSR_LOSSLESS; > +} What is 0xe0? -Scott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] powerpc/85xx: add sleep and deep sleep support
On Fri, 2015-07-24 at 20:46 +0800, Chenhui Zhao wrote: +static void mpc85xx_pmc_set_wake(struct device *dev, void *enable) { int ret; + u32 value[2]; + + if (!device_may_wakeup(dev)) + return; + + if (!pmc_regs) { + dev_err(dev, %s: PMC is unavailable\n, __func__); + return; + } + + ret = of_property_read_u32_array(dev-of_node, sleep, value, 2); This will crash on any device without an of_node. + if (ret) { + dev_dbg(dev, %s: Can not find the \sleep\ property.\n, + __func__); + return; + } + + if (*(int *)enable) + pmc_pmcdr_mask = ~value[1]; + else + pmc_pmcdr_mask |= value[1]; + + if ((value[1] 0xe0) (pmc_flag PMC_LOSSLESS)) + pmc_powmgtcsr = POWMGTCSR_LOSSLESS; +} What is 0xe0? -Scott -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] powerpc/85xx: add sleep and deep sleep support
In sleep PM mode, the clocks of e500 core and unused IP blocks is turned off. IP blocks which are allowed to wake up the processor are still running. Some Freescale chips like MPC8536 and P1022 has deep sleep PM mode in addtion to the sleep PM mode. While in deep sleep PM mode, additionally, the power supply is removed from e500 core and most IP blocks. Only the blocks needed to wake up the chip out of deep sleep are ON. This patch supports 32-bit and 36-bit address space. The sleep mode is equal to the Standby state in Linux. The deep sleep mode is equal to the Suspend-to-RAM state of Linux Power Management. Command to enter sleep mode. echo standby > /sys/power/state Command to enter deep sleep mode. echo mem > /sys/power/state Signed-off-by: Li Yang Signed-off-by: Chenhui Zhao --- arch/powerpc/include/asm/cacheflush.h | 5 + arch/powerpc/platforms/85xx/Makefile| 3 + arch/powerpc/platforms/85xx/pmc_deepsleep.S | 645 arch/powerpc/sysdev/fsl_pmc.c | 146 ++- arch/powerpc/sysdev/fsl_soc.h | 5 + 5 files changed, 785 insertions(+), 19 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/pmc_deepsleep.S diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 30b35ff..9ec4c31 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -31,6 +31,11 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_unlock(mapping) do { } while (0) extern void __flush_disable_L1(void); +#ifdef CONFIG_FSL_BOOKE +extern void flush_dcache_L1(void); +#else +#define flush_dcache_L1() do { } while (0) +#endif extern void flush_icache_range(unsigned long, unsigned long); extern void flush_icache_user_range(struct vm_area_struct *vma, diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 1fe7fb9..d187253 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -2,6 +2,9 @@ # Makefile for the PowerPC 85xx linux kernel. # obj-$(CONFIG_SMP) += smp.o +ifneq ($(CONFIG_PPC_E500MC),y) +obj-$(CONFIG_SUSPEND) += pmc_deepsleep.o +endif obj-y += common.o diff --git a/arch/powerpc/platforms/85xx/pmc_deepsleep.S b/arch/powerpc/platforms/85xx/pmc_deepsleep.S new file mode 100644 index 000..57fd4f4 --- /dev/null +++ b/arch/powerpc/platforms/85xx/pmc_deepsleep.S @@ -0,0 +1,645 @@ +/* + * Enter and leave deep sleep/sleep state on MPC85xx + * + * Author: Scott Wood + * + * Copyright 2006-2015 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#define SS_TB 0x00 +#define SS_HID 0x08 /* 2 HIDs */ +#define SS_IAC 0x10 /* 2 IACs */ +#define SS_DAC 0x18 /* 2 DACs */ +#define SS_DBCR0x20 /* 3 DBCRs */ +#define SS_PID 0x2c /* 3 PIDs */ +#define SS_SPRG0x38 /* 8 SPRGs */ +#define SS_IVOR0x58 /* 20 interrupt vectors */ +#define SS_TCR 0xa8 +#define SS_BUCSR 0xac +#define SS_L1CSR 0xb0 /* 2 L1CSRs */ +#define SS_MSR 0xb8 +#define SS_USPRG 0xbc +#define SS_GPREG 0xc0 /* r12-r31 */ +#define SS_LR 0x110 +#define SS_CR 0x114 +#define SS_SP 0x118 +#define SS_CURRENT 0x11c +#define SS_IVPR0x120 +#define SS_BPTR0x124 + + +#define STATE_SAVE_SIZE 0x128 + + .section .data + .align 5 +mpc85xx_sleep_save_area: + .space STATE_SAVE_SIZE +ccsrbase_low: + .long 0 +ccsrbase_high: + .long 0 +powmgtreq: + .long 0 + + .section .text + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +flush_disable_L2: + /* It's a write-through cache, so only invalidation is needed. */ + mbar + isync + lwz r4, 0(r3) + li r5, 1 + rlwimi r4, r5, 30, 0xc000 + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, 0x4000 + bne 1b + mbar + + blr + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +invalidate_enable_L2: + mbar + isync + lwz r4, 0(r3) + li r5, 3 + rlwimi r4, r5, 30, 0xc000 + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, 0x4000 + bne 1b + mbar + + blr + + /* +* r3 = high word of physical address of CCSR +* r4 = low word of physical address of CCSR +* r5 = JOG or deep sleep request +
[PATCH] powerpc/85xx: add sleep and deep sleep support
In sleep PM mode, the clocks of e500 core and unused IP blocks is turned off. IP blocks which are allowed to wake up the processor are still running. Some Freescale chips like MPC8536 and P1022 has deep sleep PM mode in addtion to the sleep PM mode. While in deep sleep PM mode, additionally, the power supply is removed from e500 core and most IP blocks. Only the blocks needed to wake up the chip out of deep sleep are ON. This patch supports 32-bit and 36-bit address space. The sleep mode is equal to the Standby state in Linux. The deep sleep mode is equal to the Suspend-to-RAM state of Linux Power Management. Command to enter sleep mode. echo standby /sys/power/state Command to enter deep sleep mode. echo mem /sys/power/state Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Chenhui Zhao chenhui.z...@freescale.com --- arch/powerpc/include/asm/cacheflush.h | 5 + arch/powerpc/platforms/85xx/Makefile| 3 + arch/powerpc/platforms/85xx/pmc_deepsleep.S | 645 arch/powerpc/sysdev/fsl_pmc.c | 146 ++- arch/powerpc/sysdev/fsl_soc.h | 5 + 5 files changed, 785 insertions(+), 19 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/pmc_deepsleep.S diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 30b35ff..9ec4c31 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -31,6 +31,11 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_unlock(mapping) do { } while (0) extern void __flush_disable_L1(void); +#ifdef CONFIG_FSL_BOOKE +extern void flush_dcache_L1(void); +#else +#define flush_dcache_L1() do { } while (0) +#endif extern void flush_icache_range(unsigned long, unsigned long); extern void flush_icache_user_range(struct vm_area_struct *vma, diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 1fe7fb9..d187253 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -2,6 +2,9 @@ # Makefile for the PowerPC 85xx linux kernel. # obj-$(CONFIG_SMP) += smp.o +ifneq ($(CONFIG_PPC_E500MC),y) +obj-$(CONFIG_SUSPEND) += pmc_deepsleep.o +endif obj-y += common.o diff --git a/arch/powerpc/platforms/85xx/pmc_deepsleep.S b/arch/powerpc/platforms/85xx/pmc_deepsleep.S new file mode 100644 index 000..57fd4f4 --- /dev/null +++ b/arch/powerpc/platforms/85xx/pmc_deepsleep.S @@ -0,0 +1,645 @@ +/* + * Enter and leave deep sleep/sleep state on MPC85xx + * + * Author: Scott Wood scottw...@freescale.com + * + * Copyright 2006-2015 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include asm/page.h +#include asm/ppc_asm.h +#include asm/reg.h +#include asm/asm-offsets.h + +#define SS_TB 0x00 +#define SS_HID 0x08 /* 2 HIDs */ +#define SS_IAC 0x10 /* 2 IACs */ +#define SS_DAC 0x18 /* 2 DACs */ +#define SS_DBCR0x20 /* 3 DBCRs */ +#define SS_PID 0x2c /* 3 PIDs */ +#define SS_SPRG0x38 /* 8 SPRGs */ +#define SS_IVOR0x58 /* 20 interrupt vectors */ +#define SS_TCR 0xa8 +#define SS_BUCSR 0xac +#define SS_L1CSR 0xb0 /* 2 L1CSRs */ +#define SS_MSR 0xb8 +#define SS_USPRG 0xbc +#define SS_GPREG 0xc0 /* r12-r31 */ +#define SS_LR 0x110 +#define SS_CR 0x114 +#define SS_SP 0x118 +#define SS_CURRENT 0x11c +#define SS_IVPR0x120 +#define SS_BPTR0x124 + + +#define STATE_SAVE_SIZE 0x128 + + .section .data + .align 5 +mpc85xx_sleep_save_area: + .space STATE_SAVE_SIZE +ccsrbase_low: + .long 0 +ccsrbase_high: + .long 0 +powmgtreq: + .long 0 + + .section .text + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +flush_disable_L2: + /* It's a write-through cache, so only invalidation is needed. */ + mbar + isync + lwz r4, 0(r3) + li r5, 1 + rlwimi r4, r5, 30, 0xc000 + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, 0x4000 + bne 1b + mbar + + blr + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +invalidate_enable_L2: + mbar + isync + lwz r4, 0(r3) + li r5, 3 + rlwimi r4, r5, 30, 0xc000 + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, 0x4000 + bne 1b + mbar + + blr + + /* +* r3 = high word of physical