[PATCH v5 1/5] powerpc/85xx: implement hardware timebase sync
Do hardware timebase sync. Firstly, stop all timebases, and transfer the timebase value of the boot core to the other core. Finally, start all timebases. Only apply to dual-core chips, such as MPC8572, P2020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/include/asm/fsl_guts.h |2 + arch/powerpc/platforms/85xx/smp.c | 93 +-- 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index aa4c488..dd5ba2c 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -48,6 +48,8 @@ struct ccsr_guts { __be32 dmuxcr;/* 0x.0068 - DMA Mux Control Register */ u8 res06c[0x70 - 0x6c]; __be32 devdisr;/* 0x.0070 - Device Disable Control */ +#define CCSR_GUTS_DEVDISR_TB1 0x1000 +#define CCSR_GUTS_DEVDISR_TB0 0x4000 __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ u8 res078[0x7c - 0x78]; __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index ff42490..6862dda 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -24,6 +24,7 @@ #include asm/mpic.h #include asm/cacheflush.h #include asm/dbell.h +#include asm/fsl_guts.h #include sysdev/fsl_soc.h #include sysdev/mpic.h @@ -115,13 +116,70 @@ smp_85xx_kick_cpu(int nr) struct smp_ops_t smp_85xx_ops = { .kick_cpu = smp_85xx_kick_cpu, -#ifdef CONFIG_KEXEC - .give_timebase = smp_generic_give_timebase, - .take_timebase = smp_generic_take_timebase, -#endif }; #ifdef CONFIG_KEXEC +static struct ccsr_guts __iomem *guts; +static u64 timebase; +static int tb_req; +static int tb_valid; + +static void mpc85xx_timebase_freeze(int freeze) +{ + unsigned int mask; + + if (!guts) + return; + + mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; + if (freeze) + setbits32(guts-devdisr, mask); + else + clrbits32(guts-devdisr, mask); + + in_be32(guts-devdisr); +} + +static void mpc85xx_give_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + while (!tb_req) + barrier(); + tb_req = 0; + + mpc85xx_timebase_freeze(1); + timebase = get_tb(); + mb(); + tb_valid = 1; + + while (tb_valid) + barrier(); + + mpc85xx_timebase_freeze(0); + + local_irq_restore(flags); +} + +static void mpc85xx_take_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + tb_req = 1; + while (!tb_valid) + barrier(); + + set_tb(timebase 32, timebase 0x); + mb(); + tb_valid = 0; + + local_irq_restore(flags); +} + atomic_t kexec_down_cpus = ATOMIC_INIT(0); void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) @@ -228,6 +286,20 @@ smp_85xx_setup_cpu(int cpu_nr) doorbell_setup_this_cpu(); } +#ifdef CONFIG_KEXEC +static const struct of_device_id guts_ids[] = { + { .compatible = fsl,mpc8572-guts, }, + { .compatible = fsl,mpc8560-guts, }, + { .compatible = fsl,mpc8536-guts, }, + { .compatible = fsl,p1020-guts, }, + { .compatible = fsl,p1021-guts, }, + { .compatible = fsl,p1022-guts, }, + { .compatible = fsl,p1023-guts, }, + { .compatible = fsl,p2020-guts, }, + {}, +}; +#endif + void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -249,6 +321,19 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.cause_ipi = doorbell_cause_ipi; } +#ifdef CONFIG_KEXEC + np = of_find_matching_node(NULL, guts_ids); + if (np) { + guts = of_iomap(np, 0); + smp_85xx_ops.give_timebase = mpc85xx_give_timebase; + smp_85xx_ops.take_timebase = mpc85xx_take_timebase; + of_node_put(np); + } else { + smp_85xx_ops.give_timebase = smp_generic_give_timebase; + smp_85xx_ops.take_timebase = smp_generic_take_timebase; + } +#endif + smp_ops = smp_85xx_ops; #ifdef CONFIG_KEXEC -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v5 2/5] powerpc/85xx: add HOTPLUG_CPU support
From: Li Yang le...@freescale.com Add support to disable and re-enable individual cores at runtime on MPC85xx/QorIQ SMP machines. Currently support e500v1/e500v2 core. MPC85xx machines use ePAPR spin-table in boot page for CPU kick-off. This patch uses the boot page from bootloader to boot core at runtime. It supports 32-bit and 36-bit physical address. Add generic_set_cpu_up() to set cpu_state as CPU_UP_PREPARE in kick_cpu(). Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- Changes for v5: * Used hardware timebase sync. arch/powerpc/Kconfig |6 +- arch/powerpc/include/asm/cacheflush.h |4 + arch/powerpc/include/asm/smp.h|2 + arch/powerpc/kernel/head_fsl_booke.S | 28 +++ arch/powerpc/kernel/smp.c | 10 +++ arch/powerpc/platforms/85xx/smp.c | 145 - 6 files changed, 153 insertions(+), 42 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index feab3ba..d65ae35 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -220,7 +220,8 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ - (PPC_85xx !SMP) || PPC_86xx || PPC_PSERIES || 44x || 40x + (PPC_85xx !PPC_E500MC) || PPC_86xx || PPC_PSERIES \ + || 44x || 40x config PPC_DCR_NATIVE bool @@ -331,7 +332,8 @@ config SWIOTLB config HOTPLUG_CPU bool Support for enabling/disabling CPUs - depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || PPC_PMAC || PPC_POWERNV) + depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || \ + PPC_PMAC || PPC_POWERNV || (PPC_85xx !PPC_E500MC)) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index ab9e402..94ec20a 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -30,6 +30,10 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping)do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) +#if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_6xx) +extern void __flush_disable_L1(void); +#endif + extern void __flush_icache_range(unsigned long, unsigned long); static inline void flush_icache_range(unsigned long start, unsigned long stop) { diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index ebc24dc..e807e9d 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -65,6 +65,7 @@ int generic_cpu_disable(void); void generic_cpu_die(unsigned int cpu); void generic_mach_cpu_die(void); void generic_set_cpu_dead(unsigned int cpu); +void generic_set_cpu_up(unsigned int cpu); int generic_check_cpu_restart(unsigned int cpu); #endif @@ -190,6 +191,7 @@ extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; extern char __secondary_hold; +extern void __early_start(void); #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 28e6259..0cc6f02 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -1004,6 +1004,34 @@ _GLOBAL(flush_dcache_L1) blr +/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ +_GLOBAL(__flush_disable_L1) + mflrr10 + bl flush_dcache_L1 /* Flush L1 d-cache */ + mtlrr10 + + mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + msync + isync + mtspr SPRN_L1CSR0, r4 + isync + +1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ + andi. r4, r4, 2 + bne 1b + + mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + mtspr SPRN_L1CSR1, r4 + isync + + blr + #ifdef CONFIG_SMP /* When we get here, r24 needs to hold the CPU # */ .globl __secondary_start diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index d9f9441..e0ffe03 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -423,6 +423,16 @@ void generic_set_cpu_dead(unsigned int cpu) per_cpu(cpu_state, cpu) = CPU_DEAD; } +/* + * The cpu_state should be set to CPU_UP_PREPARE in kick_cpu(), otherwise + * the cpu_state is always CPU_DEAD after calling generic_set_cpu_dead(), + * which makes the delay in generic_cpu_die() not happen. + */ +void generic_set_cpu_up(unsigned int cpu) +{ + per_cpu
[PATCH v5 3/5] powerpc/85xx: add sleep and deep sleep support
From: Li Yang le...@freescale.com 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: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Cc: Scott Wood scottw...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- Changes for v5: * Rename flush_disable_L1 to __flush_disable_L1. arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/cacheflush.h |5 + arch/powerpc/kernel/Makefile |3 + arch/powerpc/kernel/l2cache_85xx.S| 53 +++ arch/powerpc/platforms/85xx/Makefile |3 + arch/powerpc/platforms/85xx/sleep.S | 609 + arch/powerpc/sysdev/fsl_pmc.c | 91 - arch/powerpc/sysdev/fsl_soc.h |5 + 8 files changed, 752 insertions(+), 19 deletions(-) create mode 100644 arch/powerpc/kernel/l2cache_85xx.S create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d65ae35..039f0a6 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -673,7 +673,7 @@ config FSL_PCI config FSL_PMC bool default y - depends on SUSPEND (PPC_85xx || PPC_86xx) + depends on SUSPEND (PPC_85xx || PPC_86xx) !PPC_E500MC help Freescale MPC85xx/MPC86xx power management controller support (suspend/resume). For MPC83xx see platforms/83xx/suspend.c diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 94ec20a..baa000c 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -33,6 +33,11 @@ extern void flush_dcache_page(struct page *page); #if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_6xx) extern void __flush_disable_L1(void); #endif +#if defined(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); static inline void flush_icache_range(unsigned long start, unsigned long stop) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f5808a3..cb70dba 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -64,6 +64,9 @@ obj-$(CONFIG_FA_DUMP) += fadump.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o endif +ifneq ($(CONFIG_PPC_E500MC),y) +obj-$(CONFIG_PPC_85xx) += l2cache_85xx.o +endif obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o diff --git a/arch/powerpc/kernel/l2cache_85xx.S b/arch/powerpc/kernel/l2cache_85xx.S new file mode 100644 index 000..b0b7d1c --- /dev/null +++ b/arch/powerpc/kernel/l2cache_85xx.S @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2009-2012 Freescale Semiconductor, Inc. All rights reserved. + * Scott Wood scottw...@freescale.com + * Dave Liu dave...@freescale.com + * implement the L2 cache operations of e500 based L2 controller + * + * 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/reg.h +#include asm/cputable.h +#include asm/ppc_asm.h +#include asm/asm-offsets.h + + .section .text + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(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 */ +_GLOBAL(invalidate_enable_L2) + mbar + isync + lwz r4, 0(r3) + li r5, 3 + rlwimi r4, r5, 30, 0xc000 + stw r4, 0(r3) + + /* Wait
[PATCH v5 5/5] powerpc/85xx: add support to JOG feature using cpufreq interface
Some 85xx silicons like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a atomic counter to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum. Subsequent revisions of MPC8536 have corrected the erratum. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com CC: Scott Wood scottw...@freescale.com --- arch/powerpc/platforms/85xx/Makefile |1 + arch/powerpc/platforms/85xx/cpufreq-jog.c | 416 + arch/powerpc/platforms/Kconfig| 11 + arch/powerpc/sysdev/fsl_soc.h |5 + include/linux/cpu.h |4 + kernel/cpu.c | 60 ++-- 6 files changed, 467 insertions(+), 30 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/cpufreq-jog.c diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 12b526a..b49a0b6 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_SMP) += smp.o ifneq ($(CONFIG_PPC_E500MC),y) obj-$(CONFIG_SUSPEND) += sleep.o endif +obj-$(CONFIG_MPC85xx_CPUFREQ) += cpufreq-jog.o obj-y += common.o diff --git a/arch/powerpc/platforms/85xx/cpufreq-jog.c b/arch/powerpc/platforms/85xx/cpufreq-jog.c new file mode 100644 index 000..5d427ab --- /dev/null +++ b/arch/powerpc/platforms/85xx/cpufreq-jog.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2008-2012 Freescale Semiconductor, Inc. + * Author: Dave Liu dave...@freescale.com + * Modifier: Chenhui Zhao chenhui.z...@freescale.com + * + * The cpufreq driver is for Freescale 85xx processor, + * based on arch/powerpc/platforms/cell/cbe_cpufreq.c + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 + * Christian Krafft kra...@de.ibm.com + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h +#include linux/cpufreq.h +#include linux/of_platform.h +#include linux/suspend.h +#include linux/cpu.h + +#include asm/prom.h +#include asm/time.h +#include asm/reg.h +#include asm/io.h +#include asm/machdep.h +#include asm/smp.h + +#include sysdev/fsl_soc.h + +static DEFINE_MUTEX(mpc85xx_switch_mutex); +static void __iomem *guts; + +static u32 sysfreq; +static unsigned int max_pll[2]; +static atomic_t in_jog_process; +static struct cpufreq_frequency_table *mpc85xx_freqs; +static int (*set_pll)(unsigned int cpu, unsigned int pll); + +static struct cpufreq_frequency_table mpc8536_freqs_table[] = { + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +static struct cpufreq_frequency_table p1022_freqs_table[] = { + {2, 0}, + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +#define FREQ_500MHz5 +#define FREQ_800MHz8 + +#define CORE_RATIO_STRIDE 8 +#define CORE_RATIO_MASK0x3f +#define CORE_RATIO_SHIFT 16 + +#define PORPLLSR 0x0 /* Power-On Reset PLL ratio status register */ + +#define PMJCR 0x7c/* Power Management Jog Control Register */ +#define PMJCR_CORE0_SPD0x1000 +#define PMJCR_CORE_SPD 0x2000 + +#define POWMGTCSR 0x80 /* Power management control and status register */ +#define POWMGTCSR_JOG 0x0020 +#define POWMGTCSR_INT_MASK 0x0f00 + +static void spin_while_jogging(void *dummy) +{ + unsigned long flags
Re: [PATCH v5 2/5] powerpc/85xx: add HOTPLUG_CPU support
On Fri, Jun 01, 2012 at 04:27:27PM -0500, Scott Wood wrote: On 05/11/2012 06:53 AM, Zhao Chenhui wrote: \ +#if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_6xx) +extern void __flush_disable_L1(void); +#endif Prototypes aren't normally guarded by ifdefs. OK. Thanks. +static void __cpuinit smp_85xx_mach_cpu_die(void) +{ + unsigned int cpu = smp_processor_id(); + u32 tmp; + + local_irq_disable(); + idle_task_exit(); + generic_set_cpu_dead(cpu); + mb(); + + mtspr(SPRN_TCR, 0); + + __flush_disable_L1(); + tmp = (mfspr(SPRN_HID0) ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP; + mtspr(SPRN_HID0, tmp); + + /* Enter NAP mode. */ + tmp = mfmsr(); + tmp |= MSR_WE; + mb(); + mtmsr(tmp); + isync(); Need isync after writing to HID0. + /* +* We don't set the BPTR register here upon it points +* to the boot page properly. +*/ + mpic_reset_core(hw_cpu); That comment's wording is hard to follow -- maybe s/upon it points/since it already points/ + /* wait until core is ready... */ + if (!spin_event_timeout(in_be32(spin_table-addr_l) == 1, + 1, 100)) { + pr_err(%s: timeout waiting for core %d to reset\n, + __func__, hw_cpu); + ret = -ENOENT; + goto out; + } We need to fix U-Boot to write addr_l last (with an msync beforehand). I agree. -#ifdef CONFIG_KEXEC +#if defined(CONFIG_KEXEC) || defined(CONFIG_HOTPLUG_CPU) Let's not grow lists like this. Is there any harm in building it unconditionally? -Scott We need this ifdef. We only set give_timebase/take_timebase when CONFIG_KEXEC or CONFIG_HOTPLUG_CPU is defined. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 3/5] powerpc/85xx: add sleep and deep sleep support
On Fri, Jun 01, 2012 at 04:54:35PM -0500, Scott Wood wrote: On 05/11/2012 06:53 AM, Zhao Chenhui wrote: From: Li Yang le...@freescale.com 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: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Cc: Scott Wood scottw...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- Changes for v5: * Rename flush_disable_L1 to __flush_disable_L1. arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/cacheflush.h |5 + arch/powerpc/kernel/Makefile |3 + arch/powerpc/kernel/l2cache_85xx.S| 53 +++ arch/powerpc/platforms/85xx/Makefile |3 + arch/powerpc/platforms/85xx/sleep.S | 609 + arch/powerpc/sysdev/fsl_pmc.c | 91 - arch/powerpc/sysdev/fsl_soc.h |5 + 8 files changed, 752 insertions(+), 19 deletions(-) create mode 100644 arch/powerpc/kernel/l2cache_85xx.S create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 94ec20a..baa000c 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -33,6 +33,11 @@ extern void flush_dcache_page(struct page *page); #if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_6xx) extern void __flush_disable_L1(void); #endif +#if defined(CONFIG_FSL_BOOKE) +extern void flush_dcache_L1(void); +#else +#define flush_dcache_L1() do { } while (0) +#endif It doesn't seem right to no-op this on other platforms. The pmc_suspend_enter() in fsl_pmc.c used by mpc85xx and mpc86xx, but flush_dcache_L1() have no definition in mpc86xx platform. I will write flush_dcache_L1() for mpc86xx platform. extern void __flush_icache_range(unsigned long, unsigned long); static inline void flush_icache_range(unsigned long start, unsigned long stop) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f5808a3..cb70dba 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -64,6 +64,9 @@ obj-$(CONFIG_FA_DUMP) += fadump.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o endif +ifneq ($(CONFIG_PPC_E500MC),y) +obj-$(CONFIG_PPC_85xx) += l2cache_85xx.o +endif Can we introduce a symbol that specifically means pre-e500mc e500, rather than using negative logic? I think something like CONFIG_PPC_E500_V1_V2 has been proposed before. Agree. But CONFIG_PPC_E500_V1_V2 haven't been merged. -static int pmc_probe(struct platform_device *ofdev) +static int pmc_probe(struct platform_device *pdev) { - pmc_regs = of_iomap(ofdev-dev.of_node, 0); + struct device_node *np = pdev-dev.of_node; + + pmc_regs = of_iomap(np, 0); if (!pmc_regs) return -ENOMEM; - pmc_dev = ofdev-dev; + pmc_flag = PMC_SLEEP; + if (of_device_is_compatible(np, fsl,mpc8536-pmc)) + pmc_flag |= PMC_DEEP_SLEEP; + + if (of_device_is_compatible(np, fsl,p1022-pmc)) + pmc_flag |= PMC_DEEP_SLEEP; + suspend_set_ops(pmc_suspend_ops); + + pr_info(Freescale PMC driver\n); If you're going to be noisy on probe, at least provide some useful info like whether deep sleep or jog are supported. return 0; } diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index c6d0073..949377d 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -48,5 +48,10 @@ extern struct platform_diu_data_ops diu_ops; void fsl_hv_restart(char *cmd); void fsl_hv_halt(void); +/* + * Cast the ccsrbar to 64-bit parameter so that the assembly + * code can be compatible with both 32-bit 36-bit. + */ +extern void mpc85xx_enter_deep_sleep(u64 ccsrbar, u32 powmgtreq); s/Cast the ccsrbar to 64-bit parameter/ccsrbar is u64 rather than phys_addr_t/ -Scott OK. Thanks. -Chenhui
Re: [PATCH v5 4/5] fsl_pmc: Add API to enable device as wakeup event source
On Fri, Jun 01, 2012 at 05:08:52PM -0500, Scott Wood wrote: On 05/11/2012 06:53 AM, Zhao Chenhui wrote: Add APIs for setting wakeup source and lossless Ethernet in low power modes. These APIs can be used by wake-on-packet feature. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/sysdev/fsl_pmc.c | 71 - arch/powerpc/sysdev/fsl_soc.h |9 + 2 files changed, 79 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 1dc6e9e..c1170f7 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -34,6 +34,7 @@ struct pmc_regs { __be32 powmgtcsr; #define POWMGTCSR_SLP 0x0002 #define POWMGTCSR_DPSLP0x0010 +#define POWMGTCSR_LOSSLESS 0x0040 __be32 res3[2]; __be32 pmcdr; }; @@ -43,6 +44,74 @@ static unsigned int pmc_flag; #define PMC_SLEEP 0x1 #define PMC_DEEP_SLEEP 0x2 +#define PMC_LOSSLESS 0x4 + +/** + * mpc85xx_pmc_set_wake - enable devices as wakeup event source + * @pdev: platform device affected + * @enable: True to enable event generation; false to disable + * + * This enables the device as a wakeup event source, or disables it. + * + * RETURN VALUE: + * 0 is returned on success + * -EINVAL is returned if device is not supposed to wake up the system + * Error code depending on the platform is returned if both the platform and + * the native mechanism fail to enable the generation of wake-up events + */ +int mpc85xx_pmc_set_wake(struct platform_device *pdev, bool enable) Why does it have to be a platform_device? Would a bare device_node work here? If it's for stuff like device_may_wakeup() that could be in a platform_device wrapper function. It does not have to be a platform_device. I think it can be a struct device. Where does this get called from? I don't see an example user in this patchset. It will be used by a gianfar related patch. I plan to submit that patch after these patches accepted. +{ + int ret = 0; + struct device_node *clk_np; + u32 *prop; + u32 pmcdr_mask; + + if (!pmc_regs) { + pr_err(%s: PMC is unavailable\n, __func__); + return -ENODEV; + } + + if (enable !device_may_wakeup(pdev-dev)) + return -EINVAL; Who is setting can_wakeup for these devices? The device driver is responsible to set can_wakeup. + clk_np = of_parse_phandle(pdev-dev.of_node, fsl,pmc-handle, 0); + if (!clk_np) + return -EINVAL; + + prop = (u32 *)of_get_property(clk_np, fsl,pmcdr-mask, NULL); Don't cast the const away. OK. + if (!prop) { + ret = -EINVAL; + goto out; + } + pmcdr_mask = be32_to_cpup(prop); + + if (enable) + /* clear to enable clock in low power mode */ + clrbits32(pmc_regs-pmcdr, pmcdr_mask); + else + setbits32(pmc_regs-pmcdr, pmcdr_mask); What is the default PMCDR if this function is never called? Should init to all bits set on PM driver probe (or maybe limit it to defined bits only, though that's a little harder to do generically). -Scot The default PMCDR is defined separately by individual chip. I agree with you. I will have a try. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 1/5] powerpc/85xx: implement hardware timebase sync
On Fri, Jun 01, 2012 at 10:40:00AM -0500, Scott Wood wrote: On 05/11/2012 06:53 AM, Zhao Chenhui wrote: #ifdef CONFIG_KEXEC +static struct ccsr_guts __iomem *guts; +static u64 timebase; +static int tb_req; +static int tb_valid; + +static void mpc85xx_timebase_freeze(int freeze) Why is this under CONFIG_KEXEC? It'll also be needed for CPU hotplug. Yes, the timebase sync is also needed for CPU hotplug, but this patch is unrelated to CPU hotplug. I added CONFIG_HOTPLUG_CPU in the next patch. +{ + unsigned int mask; + + if (!guts) + return; + + mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; + if (freeze) + setbits32(guts-devdisr, mask); + else + clrbits32(guts-devdisr, mask); + + in_be32(guts-devdisr); +} + +static void mpc85xx_give_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + while (!tb_req) + barrier(); + tb_req = 0; + + mpc85xx_timebase_freeze(1); + timebase = get_tb(); + mb(); + tb_valid = 1; + + while (tb_valid) + barrier(); + + mpc85xx_timebase_freeze(0); + + local_irq_restore(flags); +} + +static void mpc85xx_take_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + tb_req = 1; + while (!tb_valid) + barrier(); + + set_tb(timebase 32, timebase 0x); + mb(); + tb_valid = 0; + + local_irq_restore(flags); +} I know you say this is for dual-core chips only, but it would be nice if you'd write this in a way that doesn't assume that (even if the corenet-specific timebase freezing comes later). At this point, I have not thought about how to implement the cornet-specific timebase freezing. Do we need an isync after setting the timebase, to ensure it's happened before we enable the timebase? Likewise, do we need a readback after disabling the timebase to ensure it's disabled before we read the timebase in give_timebase? I checked the e500 core manual (Chapter 2.16 Synchronization Requirements for SPRs). Only some SPR registers need an isync. The timebase registers do not. I did a readback in mpc85xx_timebase_freeze(). atomic_t kexec_down_cpus = ATOMIC_INIT(0); void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) @@ -228,6 +286,20 @@ smp_85xx_setup_cpu(int cpu_nr) doorbell_setup_this_cpu(); } +#ifdef CONFIG_KEXEC +static const struct of_device_id guts_ids[] = { + { .compatible = fsl,mpc8572-guts, }, + { .compatible = fsl,mpc8560-guts, }, + { .compatible = fsl,mpc8536-guts, }, + { .compatible = fsl,p1020-guts, }, + { .compatible = fsl,p1021-guts, }, + { .compatible = fsl,p1022-guts, }, + { .compatible = fsl,p1023-guts, }, + { .compatible = fsl,p2020-guts, }, + {}, +}; +#endif MPC8560 and MPC8536 are single-core... Thanks. I will remove them. Also please use a more specific name, such as e500v2_smp_guts_ids or mpc85xx_smp_guts_ids -- when corenet support is added it will likely be in the same file. void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -249,6 +321,19 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.cause_ipi = doorbell_cause_ipi; } +#ifdef CONFIG_KEXEC + np = of_find_matching_node(NULL, guts_ids); + if (np) { + guts = of_iomap(np, 0); + smp_85xx_ops.give_timebase = mpc85xx_give_timebase; + smp_85xx_ops.take_timebase = mpc85xx_take_timebase; + of_node_put(np); + } else { + smp_85xx_ops.give_timebase = smp_generic_give_timebase; + smp_85xx_ops.take_timebase = smp_generic_take_timebase; + } Do not use smp_generic_give/take_timebase, ever. If you don't have the guts node, then just assume the timebase is already synced. -Scott smp_generic_give/take_timebase is the default in KEXEC before. If do not set them, it may make KEXEC fail on other platforms. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 5/5] powerpc/85xx: add support to JOG feature using cpufreq interface
On Fri, Jun 01, 2012 at 06:30:55PM -0500, Scott Wood wrote: On 05/11/2012 06:53 AM, Zhao Chenhui wrote: Some 85xx silicons like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. Is there a reason P1023 isn't supported? P1023 support is deferred. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a atomic counter to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. That might be acceptable for eTSEC, but it is not acceptable to lose anything on PCIe. Especially not if you're going to make this default y. It is a hardware limitation. Peripherals in the platform will not be operating during the jog mode frequency transition process. I can make it default n. +static int mpc85xx_job_probe(struct platform_device *ofdev) Job? Sorry, It should be jog. +{ + struct device_node *np = ofdev-dev.of_node; + unsigned int svr; + + if (of_device_is_compatible(np, fsl,mpc8536-guts)) { + svr = mfspr(SPRN_SVR); + if ((svr 0x7fff) == 0x10) { + pr_err(MPC8536 Rev 1.0 do not support JOG.\n); + return -ENODEV; + } s/do not support JOG/does not support cpufreq/ + mpc85xx_freqs = mpc8536_freqs_table; + set_pll = mpc8536_set_pll; + } else if (of_device_is_compatible(np, fsl,p1022-guts)) { + mpc85xx_freqs = p1022_freqs_table; + set_pll = p1022_set_pll; + } else { + return -ENODEV; + } + + sysfreq = fsl_get_sys_freq(); + + guts = of_iomap(np, 0); + if (!guts) + return -ENODEV; + + max_pll[0] = get_pll(0); + if (mpc85xx_freqs == p1022_freqs_table) + max_pll[1] = get_pll(1); + + pr_info(Freescale MPC85xx CPU frequency switching(JOG) driver\n); + + return cpufreq_register_driver(mpc85xx_cpufreq_driver); +} + +static int mpc85xx_jog_remove(struct platform_device *ofdev) +{ + iounmap(guts); + cpufreq_unregister_driver(mpc85xx_cpufreq_driver); + + return 0; +} + +static struct of_device_id mpc85xx_jog_ids[] = { + { .compatible = fsl,mpc8536-guts, }, + { .compatible = fsl,p1022-guts, }, + {} +}; + +static struct platform_driver mpc85xx_jog_driver = { + .driver = { + .name = mpc85xx_cpufreq_jog, + .owner = THIS_MODULE, + .of_match_table = mpc85xx_jog_ids, + }, + .probe = mpc85xx_job_probe, + .remove = mpc85xx_jog_remove, +}; Why is this a separate driver from fsl_pmc.c? Only one driver can bind to a node through normal mechanisms -- you don't get to take the entire guts node for this. You are right. I will not bind this to the guts node. +static int __init mpc85xx_jog_init(void) +{ + return platform_driver_register(mpc85xx_jog_driver); +} + +static void __exit mpc85xx_jog_exit(void) +{ + platform_driver_unregister(mpc85xx_jog_driver); +} + +module_init(mpc85xx_jog_init); +module_exit(mpc85xx_jog_exit); + +MODULE_LICENSE(GPL); +MODULE_AUTHOR(Dave Liu dave...@freescale.com); diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index a35ca44..445bedd 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -204,6 +204,17 @@ config CPU_FREQ_PMAC64 This adds support for frequency switching on Apple iMac G5, and some of the more recent desktop G5 machines as well. +config MPC85xx_CPUFREQ + bool Support for Freescale MPC85xx CPU freq + depends on PPC_85xx PPC32 !PPC_E500MC PPC32 is redundant given the !PPC_E500MC. Yes. index 8976534..401cac0 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -62,5 +62,10 @@ void fsl_hv_halt(void); * code can be compatible with both 32-bit 36-bit. */ extern void mpc85xx_enter_deep_sleep(u64 ccsrbar, u32 powmgtreq); + +static inline void mpc85xx_enter_jog(u64 ccsrbar, u32 powmgtreq) +{ + mpc85xx_enter_deep_sleep(ccsrbar, powmgtreq); +} What value is this function adding over mpc85xx_enter_deep_sleep()? Just an alias name. If this is improper, I could use mpc85xx_enter_deep_sleep() directly. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 2/5] powerpc/85xx: add HOTPLUG_CPU support
On Mon, Jun 04, 2012 at 11:32:47AM -0500, Scott Wood wrote: On 06/04/2012 06:04 AM, Zhao Chenhui wrote: On Fri, Jun 01, 2012 at 04:27:27PM -0500, Scott Wood wrote: On 05/11/2012 06:53 AM, Zhao Chenhui wrote: -#ifdef CONFIG_KEXEC +#if defined(CONFIG_KEXEC) || defined(CONFIG_HOTPLUG_CPU) Let's not grow lists like this. Is there any harm in building it unconditionally? -Scott We need this ifdef. We only set give_timebase/take_timebase when CONFIG_KEXEC or CONFIG_HOTPLUG_CPU is defined. If we really need this to be a compile-time decision, make a new symbol for it, but I really think this should be decided at runtime. Just because we have kexec or hotplug support enabled doesn't mean that's actually what we're doing at the moment. -Scott If user does not enable kexec or hotplug, these codes are redundant. So use CONFIG_KEXEC and CONFIG_HOTPLUG_CPU to gard them. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 3/5] powerpc/85xx: add sleep and deep sleep support
On Mon, Jun 04, 2012 at 05:58:38PM -0500, Scott Wood wrote: On 06/04/2012 06:12 AM, Zhao Chenhui wrote: On Fri, Jun 01, 2012 at 04:54:35PM -0500, Scott Wood wrote: On 05/11/2012 06:53 AM, Zhao Chenhui wrote: diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 94ec20a..baa000c 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -33,6 +33,11 @@ extern void flush_dcache_page(struct page *page); #if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_6xx) extern void __flush_disable_L1(void); #endif +#if defined(CONFIG_FSL_BOOKE) +extern void flush_dcache_L1(void); +#else +#define flush_dcache_L1()do { } while (0) +#endif It doesn't seem right to no-op this on other platforms. The pmc_suspend_enter() in fsl_pmc.c used by mpc85xx and mpc86xx, but flush_dcache_L1() have no definition in mpc86xx platform. I will write flush_dcache_L1() for mpc86xx platform. How about only calling the function when it's needed? If we didn't need an L1 flush here on 86xx before, why do we need it now? How about using CONFIG_PPC_85xx to gard it, like this. case PM_SUSPEND_STANDBY: local_irq_disable(); #ifdef CONFIG_PPC_85xx flush_dcache_L1(); #endif setbits32(pmc_regs-powmgtcsr, POWMGTCSR_SLP); extern void __flush_icache_range(unsigned long, unsigned long); static inline void flush_icache_range(unsigned long start, unsigned long stop) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f5808a3..cb70dba 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -64,6 +64,9 @@ obj-$(CONFIG_FA_DUMP) += fadump.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o endif +ifneq ($(CONFIG_PPC_E500MC),y) +obj-$(CONFIG_PPC_85xx) += l2cache_85xx.o +endif Can we introduce a symbol that specifically means pre-e500mc e500, rather than using negative logic? I think something like CONFIG_PPC_E500_V1_V2 has been proposed before. Agree. But CONFIG_PPC_E500_V1_V2 haven't been merged. Has the concept been NACKed, or just forgotten? If the latter, you could include it in this patchset. -Scott In patchwork, it's state is Superseded. http://patchwork.ozlabs.org/patch/124284/ -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 1/5] powerpc/85xx: implement hardware timebase sync
On Tue, Jun 05, 2012 at 11:07:41AM -0500, Scott Wood wrote: On 06/05/2012 04:08 AM, Zhao Chenhui wrote: On Fri, Jun 01, 2012 at 10:40:00AM -0500, Scott Wood wrote: I know you say this is for dual-core chips only, but it would be nice if you'd write this in a way that doesn't assume that (even if the corenet-specific timebase freezing comes later). At this point, I have not thought about how to implement the cornet-specific timebase freezing. I wasn't asking you to. I was asking you to not have logic that breaks with more than 2 CPUs. These routines only called in the dual-core case. Do we need an isync after setting the timebase, to ensure it's happened before we enable the timebase? Likewise, do we need a readback after disabling the timebase to ensure it's disabled before we read the timebase in give_timebase? I checked the e500 core manual (Chapter 2.16 Synchronization Requirements for SPRs). Only some SPR registers need an isync. The timebase registers do not. I don't trust that, and the consequences of having the sync be imperfect are too unpleasant to chance it. I did a readback in mpc85xx_timebase_freeze(). Sorry, missed that somehow. +#ifdef CONFIG_KEXEC + np = of_find_matching_node(NULL, guts_ids); + if (np) { + guts = of_iomap(np, 0); + smp_85xx_ops.give_timebase = mpc85xx_give_timebase; + smp_85xx_ops.take_timebase = mpc85xx_take_timebase; + of_node_put(np); + } else { + smp_85xx_ops.give_timebase = smp_generic_give_timebase; + smp_85xx_ops.take_timebase = smp_generic_take_timebase; + } Do not use smp_generic_give/take_timebase, ever. If you don't have the guts node, then just assume the timebase is already synced. -Scott smp_generic_give/take_timebase is the default in KEXEC before. That was a mistake. If do not set them, it may make KEXEC fail on other platforms. What platforms? -Scott Such as P4080, P3041, etc. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 2/5] powerpc/85xx: add HOTPLUG_CPU support
On Tue, Jun 05, 2012 at 11:15:52AM -0500, Scott Wood wrote: On 06/05/2012 06:18 AM, Zhao Chenhui wrote: On Mon, Jun 04, 2012 at 11:32:47AM -0500, Scott Wood wrote: On 06/04/2012 06:04 AM, Zhao Chenhui wrote: On Fri, Jun 01, 2012 at 04:27:27PM -0500, Scott Wood wrote: On 05/11/2012 06:53 AM, Zhao Chenhui wrote: -#ifdef CONFIG_KEXEC +#if defined(CONFIG_KEXEC) || defined(CONFIG_HOTPLUG_CPU) Let's not grow lists like this. Is there any harm in building it unconditionally? -Scott We need this ifdef. We only set give_timebase/take_timebase when CONFIG_KEXEC or CONFIG_HOTPLUG_CPU is defined. If we really need this to be a compile-time decision, make a new symbol for it, but I really think this should be decided at runtime. Just because we have kexec or hotplug support enabled doesn't mean that's actually what we're doing at the moment. -Scott If user does not enable kexec or hotplug, these codes are redundant. So use CONFIG_KEXEC and CONFIG_HOTPLUG_CPU to gard them. My point is that these lists tend to grow and be a maintenance pain. For small things it's often better to not worry about saving a few bytes. For larger things that need to be conditional, define a new symbol rather than growing ORed lists like this. -Scott I agree with you in principle. But there are only two config options in this patch, and it is unlikely to grow. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 5/5] powerpc/85xx: add support to JOG feature using cpufreq interface
On Tue, Jun 05, 2012 at 10:58:41AM -0500, Scott Wood wrote: On 06/05/2012 05:59 AM, Zhao Chenhui wrote: On Fri, Jun 01, 2012 at 06:30:55PM -0500, Scott Wood wrote: On 05/11/2012 06:53 AM, Zhao Chenhui wrote: The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. That might be acceptable for eTSEC, but it is not acceptable to lose anything on PCIe. Especially not if you're going to make this default y. It is a hardware limitation. Then make sure jog isn't used if PCIe is used. Maybe you could do something with the suspend infrastructure, but this is sufficiently heavyweight that transitions should be manually requested, not triggered by the automatic cpufreq governor. Does this apply to p1022, or just mpc8536? Both of them. Peripherals in the platform will not be operating during the jog mode frequency transition process. What ensures this? -Scott Hardware ensures it without software intervention. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 1/5] powerpc/85xx: implement hardware timebase sync
On Wed, Jun 06, 2012 at 01:26:16PM -0500, Scott Wood wrote: On 06/06/2012 04:31 AM, Zhao Chenhui wrote: On Tue, Jun 05, 2012 at 11:07:41AM -0500, Scott Wood wrote: On 06/05/2012 04:08 AM, Zhao Chenhui wrote: On Fri, Jun 01, 2012 at 10:40:00AM -0500, Scott Wood wrote: I know you say this is for dual-core chips only, but it would be nice if you'd write this in a way that doesn't assume that (even if the corenet-specific timebase freezing comes later). At this point, I have not thought about how to implement the cornet-specific timebase freezing. I wasn't asking you to. I was asking you to not have logic that breaks with more than 2 CPUs. These routines only called in the dual-core case. Come on, you know we have chips with more than two cores. Why design such a limitation into it, just because you're not personally interested in supporting anything but e500v2? Is it so hard to make it work for an arbitrary number of cores? If do not set them, it may make KEXEC fail on other platforms. What platforms? Such as P4080, P3041, etc. So we need to wait for corenet timebase sync before we stop causing problems in virtualization, simulators, etc. if a kernel has kexec or cpu hotplug enabled (whether used or not)? Can you at least make sure we're actually in a kexec/hotplug scenario at runtime? Or just implement corenet timebase sync -- it's not that different. -Scott We also work on the corenet timebase sync. Our plan is first the dual-core case, then the case of more than 2 cores. We will submit the corenet timebase sync patch soon. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v6 1/5] powerpc/85xx: implement hardware timebase sync
Do hardware timebase sync. Firstly, stop all timebases, and transfer the timebase value of the boot core to the other core. Finally, start all timebases. Only apply to dual-core chips, such as MPC8572, P2020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- Changes for v6: * added 85xx_TB_SYNC * added isync() after set_tb() * removed extra entries from mpc85xx_smp_guts_ids arch/powerpc/include/asm/fsl_guts.h |2 + arch/powerpc/platforms/85xx/Kconfig |5 ++ arch/powerpc/platforms/85xx/smp.c | 84 +++ 3 files changed, 91 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index aa4c488..dd5ba2c 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -48,6 +48,8 @@ struct ccsr_guts { __be32 dmuxcr;/* 0x.0068 - DMA Mux Control Register */ u8 res06c[0x70 - 0x6c]; __be32 devdisr;/* 0x.0070 - Device Disable Control */ +#define CCSR_GUTS_DEVDISR_TB1 0x1000 +#define CCSR_GUTS_DEVDISR_TB0 0x4000 __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ u8 res078[0x7c - 0x78]; __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */ diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index f000d81..8dd7147 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -8,6 +8,7 @@ menuconfig FSL_SOC_BOOKE select FSL_PCI if PCI select SERIAL_8250_EXTENDED if SERIAL_8250 select SERIAL_8250_SHARE_IRQ if SERIAL_8250 + select 85xx_TB_SYNC if KEXEC default y if FSL_SOC_BOOKE @@ -267,3 +268,7 @@ endif # FSL_SOC_BOOKE config TQM85xx bool + +config 85xx_TB_SYNC + bool + default n diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index ff42490..edb0cad 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -24,6 +24,7 @@ #include asm/mpic.h #include asm/cacheflush.h #include asm/dbell.h +#include asm/fsl_guts.h #include sysdev/fsl_soc.h #include sysdev/mpic.h @@ -42,6 +43,69 @@ extern void __early_start(void); #define NUM_BOOT_ENTRY 8 #define SIZE_BOOT_ENTRY(NUM_BOOT_ENTRY * sizeof(u32)) +#ifdef CONFIG_85xx_TB_SYNC +static struct ccsr_guts __iomem *guts; +static u64 timebase; +static int tb_req; +static int tb_valid; + +static void mpc85xx_timebase_freeze(int freeze) +{ + unsigned int mask; + + if (!guts) + return; + + mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; + if (freeze) + setbits32(guts-devdisr, mask); + else + clrbits32(guts-devdisr, mask); + + in_be32(guts-devdisr); +} + +static void mpc85xx_give_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + while (!tb_req) + barrier(); + tb_req = 0; + + mpc85xx_timebase_freeze(1); + timebase = get_tb(); + mb(); + tb_valid = 1; + + while (tb_valid) + barrier(); + + mpc85xx_timebase_freeze(0); + + local_irq_restore(flags); +} + +static void mpc85xx_take_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + tb_req = 1; + while (!tb_valid) + barrier(); + + set_tb(timebase 32, timebase 0x); + isync(); + tb_valid = 0; + + local_irq_restore(flags); +} +#endif + static int __init smp_85xx_kick_cpu(int nr) { @@ -228,6 +292,16 @@ smp_85xx_setup_cpu(int cpu_nr) doorbell_setup_this_cpu(); } +static const struct of_device_id mpc85xx_smp_guts_ids[] = { + { .compatible = fsl,mpc8572-guts, }, + { .compatible = fsl,p1020-guts, }, + { .compatible = fsl,p1021-guts, }, + { .compatible = fsl,p1022-guts, }, + { .compatible = fsl,p1023-guts, }, + { .compatible = fsl,p2020-guts, }, + {}, +}; + void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -249,6 +323,16 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.cause_ipi = doorbell_cause_ipi; } + np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); + if (np) { +#ifdef CONFIG_85xx_TB_SYNC + guts = of_iomap(np, 0); + smp_85xx_ops.give_timebase = mpc85xx_give_timebase; + smp_85xx_ops.take_timebase = mpc85xx_take_timebase; +#endif + of_node_put(np); + } + smp_ops = smp_85xx_ops; #ifdef CONFIG_KEXEC -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v6 2/5] powerpc/85xx: add HOTPLUG_CPU support
From: Li Yang le...@freescale.com Add support to disable and re-enable individual cores at runtime on MPC85xx/QorIQ SMP machines. Currently support e500v1/e500v2 core. MPC85xx machines use ePAPR spin-table in boot page for CPU kick-off. This patch uses the boot page from bootloader to boot core at runtime. It supports 32-bit and 36-bit physical address. Add generic_set_cpu_up() to set cpu_state as CPU_UP_PREPARE in kick_cpu(). Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- Changes for v6: * do not guard __flush_disable_L1() by ifdefs * added isync() after mtspr() arch/powerpc/Kconfig |6 +- arch/powerpc/include/asm/cacheflush.h |2 + arch/powerpc/include/asm/smp.h|2 + arch/powerpc/kernel/head_fsl_booke.S | 28 +++ arch/powerpc/kernel/smp.c | 10 +++ arch/powerpc/platforms/85xx/Kconfig |2 +- arch/powerpc/platforms/85xx/smp.c | 137 - 7 files changed, 147 insertions(+), 40 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 38786c8..d6bacbe 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -220,7 +220,8 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ - (PPC_85xx !SMP) || PPC_86xx || PPC_PSERIES || 44x || 40x + (PPC_85xx !PPC_E500MC) || PPC_86xx || PPC_PSERIES \ + || 44x || 40x config PPC_DCR_NATIVE bool @@ -331,7 +332,8 @@ config SWIOTLB config HOTPLUG_CPU bool Support for enabling/disabling CPUs - depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || PPC_PMAC || PPC_POWERNV) + depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || \ + PPC_PMAC || PPC_POWERNV || (PPC_85xx !PPC_E500MC)) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index ab9e402..b843e35 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -30,6 +30,8 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping)do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) +extern void __flush_disable_L1(void); + extern void __flush_icache_range(unsigned long, unsigned long); static inline void flush_icache_range(unsigned long start, unsigned long stop) { diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index ebc24dc..e807e9d 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -65,6 +65,7 @@ int generic_cpu_disable(void); void generic_cpu_die(unsigned int cpu); void generic_mach_cpu_die(void); void generic_set_cpu_dead(unsigned int cpu); +void generic_set_cpu_up(unsigned int cpu); int generic_check_cpu_restart(unsigned int cpu); #endif @@ -190,6 +191,7 @@ extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; extern char __secondary_hold; +extern void __early_start(void); #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index de80e0f..be0261b 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -996,6 +996,34 @@ _GLOBAL(flush_dcache_L1) blr +/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ +_GLOBAL(__flush_disable_L1) + mflrr10 + bl flush_dcache_L1 /* Flush L1 d-cache */ + mtlrr10 + + mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + msync + isync + mtspr SPRN_L1CSR0, r4 + isync + +1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ + andi. r4, r4, 2 + bne 1b + + mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + mtspr SPRN_L1CSR1, r4 + isync + + blr + #ifdef CONFIG_SMP /* When we get here, r24 needs to hold the CPU # */ .globl __secondary_start diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index d9f9441..e0ffe03 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -423,6 +423,16 @@ void generic_set_cpu_dead(unsigned int cpu) per_cpu(cpu_state, cpu) = CPU_DEAD; } +/* + * The cpu_state should be set to CPU_UP_PREPARE in kick_cpu(), otherwise + * the cpu_state is always CPU_DEAD after calling generic_set_cpu_dead(), + * which makes the delay in generic_cpu_die() not happen. + */ +void generic_set_cpu_up(unsigned int
[PATCH v6 4/5] fsl_pmc: Add API to enable device as wakeup event source
Add APIs for setting wakeup source and lossless Ethernet in low power modes. These APIs can be used by wake-on-packet feature. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- Changes for v6: * changed the parameter of mpc85xx_pmc_set_wake() * set an initial value to PMCDR register arch/powerpc/sysdev/fsl_pmc.c | 77 - arch/powerpc/sysdev/fsl_soc.h | 12 ++ 2 files changed, 88 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 45718c5..b6c8c8f 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -38,6 +38,7 @@ struct pmc_regs { __be32 powmgtcsr; #define POWMGTCSR_SLP 0x0002 #define POWMGTCSR_DPSLP0x0010 +#define POWMGTCSR_LOSSLESS 0x0040 __be32 res3[2]; /* 0xe008c: Power management clock disable register */ __be32 pmcdr; @@ -48,6 +49,77 @@ static unsigned int pmc_flag; #define PMC_SLEEP 0x1 #define PMC_DEEP_SLEEP 0x2 +#define PMC_LOSSLESS 0x4 + +#define PMCDR_MASK_INIT0x00e008e0 + +/** + * mpc85xx_pmc_set_wake - enable devices as wakeup event source + * @dev: a device affected + * @enable: True to enable event generation; false to disable + * + * This enables the device as a wakeup event source, or disables it. + * + * RETURN VALUE: + * 0 is returned on success. + * -EINVAL is returned if device is not supposed to wake up the system. + * -ENODEV is returned if PMC is unavailable. + * Error code depending on the platform is returned if both the platform and + * the native mechanism fail to enable the generation of wake-up events + */ +int mpc85xx_pmc_set_wake(struct device *dev, bool enable) +{ + int ret = 0; + struct device_node *clk_np; + const u32 *prop; + u32 pmcdr_mask; + + if (!pmc_regs) { + pr_err(%s: PMC is unavailable\n, __func__); + return -ENODEV; + } + + if (enable !device_may_wakeup(dev)) + return -EINVAL; + + clk_np = of_parse_phandle(dev-of_node, fsl,pmc-handle, 0); + if (!clk_np) + return -EINVAL; + + prop = of_get_property(clk_np, fsl,pmcdr-mask, NULL); + if (!prop) { + ret = -EINVAL; + goto out; + } + pmcdr_mask = be32_to_cpup(prop); + + if (enable) + /* clear to enable clock in low power mode */ + clrbits32(pmc_regs-pmcdr, pmcdr_mask); + else + setbits32(pmc_regs-pmcdr, pmcdr_mask); + +out: + of_node_put(clk_np); + return ret; +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_wake); + +/** + * mpc85xx_pmc_set_lossless_ethernet - enable lossless ethernet + * in (deep) sleep mode + * @enable: True to enable event generation; false to disable + */ +void mpc85xx_pmc_set_lossless_ethernet(int enable) +{ + if (pmc_flag PMC_LOSSLESS) { + if (enable) + setbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + else + clrbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + } +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_lossless_ethernet); static int pmc_suspend_enter(suspend_state_t state) { @@ -123,7 +195,10 @@ static int pmc_probe(struct platform_device *pdev) pmc_flag |= PMC_DEEP_SLEEP; if (of_device_is_compatible(np, fsl,p1022-pmc)) - pmc_flag |= PMC_DEEP_SLEEP; + pmc_flag |= PMC_DEEP_SLEEP | PMC_LOSSLESS; + + /* Init the Power Management Clock Disable Register. */ + setbits32(pmc_regs-pmcdr, PMCDR_MASK_INIT); suspend_set_ops(pmc_suspend_ops); diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 11d9f94..b1510ef 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -3,6 +3,7 @@ #ifdef __KERNEL__ #include asm/mmu.h +#include linux/platform_device.h struct spi_device; @@ -21,6 +22,17 @@ struct device_node; extern void fsl_rstcr_restart(char *cmd); +#ifdef CONFIG_FSL_PMC +extern int mpc85xx_pmc_set_wake(struct device *dev, bool enable); +extern void mpc85xx_pmc_set_lossless_ethernet(int enable); +#else +static inline int mpc85xx_pmc_set_wake(struct device *dev, bool enable) +{ + return -ENODEV; +} +#define mpc85xx_pmc_set_lossless_ethernet(enable) do { } while (0) +#endif + #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) /* The different ports that the DIU can be connected to */ -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v6 5/5] powerpc/85xx: add support to JOG feature using cpufreq interface
Some 85xx silicons like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a atomic counter to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum. Subsequent revisions of MPC8536 have corrected the erratum. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com CC: Scott Wood scottw...@freescale.com --- Changes for v6: * changed mpc85xx_jog_probe() * call mpc85xx_jog_probe() in arch/powerpc/sysdev/fsl_pmc.c * removed changes of kernel/cpu.c arch/powerpc/platforms/85xx/Makefile |1 + arch/powerpc/platforms/85xx/cpufreq-jog.c | 388 + arch/powerpc/platforms/Kconfig| 11 + arch/powerpc/sysdev/fsl_pmc.c |3 + arch/powerpc/sysdev/fsl_soc.h |2 + include/linux/cpu.h |4 + 6 files changed, 409 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/cpufreq-jog.c diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index d154e39..8681a5c 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_SMP) += smp.o obj-y += common.o sleep.o +obj-$(CONFIG_MPC85xx_CPUFREQ) += cpufreq-jog.o obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o diff --git a/arch/powerpc/platforms/85xx/cpufreq-jog.c b/arch/powerpc/platforms/85xx/cpufreq-jog.c new file mode 100644 index 000..ccc0c33 --- /dev/null +++ b/arch/powerpc/platforms/85xx/cpufreq-jog.c @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2008-2012 Freescale Semiconductor, Inc. + * Author: Dave Liu dave...@freescale.com + * Modifier: Chenhui Zhao chenhui.z...@freescale.com + * + * The cpufreq driver is for Freescale 85xx processor, + * based on arch/powerpc/platforms/cell/cbe_cpufreq.c + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 + * Christian Krafft kra...@de.ibm.com + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h +#include linux/cpufreq.h +#include linux/of_platform.h +#include linux/suspend.h +#include linux/cpu.h + +#include asm/prom.h +#include asm/time.h +#include asm/reg.h +#include asm/io.h +#include asm/machdep.h +#include asm/smp.h + +#include sysdev/fsl_soc.h + +static DEFINE_MUTEX(mpc85xx_switch_mutex); +static void __iomem *guts; + +static u32 sysfreq; +static unsigned int max_pll[2]; +static atomic_t in_jog_process; +static struct cpufreq_frequency_table *mpc85xx_freqs; +static int (*set_pll)(unsigned int cpu, unsigned int pll); + +static struct cpufreq_frequency_table mpc8536_freqs_table[] = { + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +static struct cpufreq_frequency_table p1022_freqs_table[] = { + {2, 0}, + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +#define FREQ_500MHz5 +#define FREQ_800MHz8 + +#define CORE_RATIO_STRIDE 8 +#define CORE_RATIO_MASK0x3f +#define CORE_RATIO_SHIFT 16 + +#define PORPLLSR 0x0 /* Power-On Reset PLL ratio status register */ + +#define PMJCR 0x7c/* Power Management Jog Control Register */ +#define PMJCR_CORE0_SPD0x1000 +#define PMJCR_CORE_SPD 0x2000 + +#define POWMGTCSR 0x80 /* Power management control and status register
[PATCH v6 3/5] powerpc/85xx: add sleep and deep sleep support
From: Li Yang le...@freescale.com 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: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Cc: Scott Wood scottw...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- Changes for v6: * changed the declaration of flush_dcache_L1() * some minor changes arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/cacheflush.h |2 + arch/powerpc/kernel/Makefile |3 + arch/powerpc/kernel/l2cache_85xx.S| 53 +++ arch/powerpc/platforms/85xx/Makefile |2 +- arch/powerpc/platforms/85xx/sleep.S | 609 + arch/powerpc/sysdev/fsl_pmc.c | 98 +- arch/powerpc/sysdev/fsl_soc.h |5 + 8 files changed, 754 insertions(+), 20 deletions(-) create mode 100644 arch/powerpc/kernel/l2cache_85xx.S create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d6bacbe..6883769 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -673,7 +673,7 @@ config FSL_PCI config FSL_PMC bool default y - depends on SUSPEND (PPC_85xx || PPC_86xx) + depends on SUSPEND (PPC_85xx || PPC_86xx) !PPC_E500MC help Freescale MPC85xx/MPC86xx power management controller support (suspend/resume). For MPC83xx see platforms/83xx/suspend.c diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index b843e35..6c5f1c2 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -58,6 +58,8 @@ extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); #endif +extern void flush_dcache_L1(void); + #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ memcpy(dst, src, len); \ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f5808a3..cb70dba 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -64,6 +64,9 @@ obj-$(CONFIG_FA_DUMP) += fadump.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o endif +ifneq ($(CONFIG_PPC_E500MC),y) +obj-$(CONFIG_PPC_85xx) += l2cache_85xx.o +endif obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o diff --git a/arch/powerpc/kernel/l2cache_85xx.S b/arch/powerpc/kernel/l2cache_85xx.S new file mode 100644 index 000..b0b7d1c --- /dev/null +++ b/arch/powerpc/kernel/l2cache_85xx.S @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2009-2012 Freescale Semiconductor, Inc. All rights reserved. + * Scott Wood scottw...@freescale.com + * Dave Liu dave...@freescale.com + * implement the L2 cache operations of e500 based L2 controller + * + * 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/reg.h +#include asm/cputable.h +#include asm/ppc_asm.h +#include asm/asm-offsets.h + + .section .text + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(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 */ +_GLOBAL(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
Re: [PATCH v6 1/5] powerpc/85xx: implement hardware timebase sync
On Tue, Jun 26, 2012 at 09:03:42AM -0500, Kumar Gala wrote: On Jun 26, 2012, at 5:25 AM, Zhao Chenhui wrote: Do hardware timebase sync. Firstly, stop all timebases, and transfer the timebase value of the boot core to the other core. Finally, start all timebases. Only apply to dual-core chips, such as MPC8572, P2020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- Changes for v6: * added 85xx_TB_SYNC * added isync() after set_tb() * removed extra entries from mpc85xx_smp_guts_ids Why only on dual-core chips? Is this because of something related to 2 cores, or related to corenet vs non-corenet SoCs and how turning on/off the timebase works in the SOC? - k I am working on a timebase sync patch for corenet SoCs which have more than 2 cores. It is based on this patch. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v6 1/5] powerpc/85xx: implement hardware timebase sync
On Wed, Jun 27, 2012 at 08:10:34AM +1000, Benjamin Herrenschmidt wrote: On Tue, 2012-06-26 at 18:25 +0800, Zhao Chenhui wrote: Do hardware timebase sync. Firstly, stop all timebases, and transfer the timebase value of the boot core to the other core. Finally, start all timebases. Only apply to dual-core chips, such as MPC8572, P2020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- Changes for v6: * added 85xx_TB_SYNC * added isync() after set_tb() * removed extra entries from mpc85xx_smp_guts_ids What's that CONFIG option for ? Cheers, Ben. This option is to guard the timebase sync routines. It is selected when KEXEC or HOTPLUG_CPU is enabled on Freescale Book-E platforms. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v6 1/5] powerpc/85xx: implement hardware timebase sync
On Wed, Jun 27, 2012 at 09:48:52PM +1000, Benjamin Herrenschmidt wrote: On Wed, 2012-06-27 at 18:21 +0800, Zhao Chenhui wrote: What's that CONFIG option for ? Cheers, Ben. This option is to guard the timebase sync routines. It is selected when KEXEC or HOTPLUG_CPU is enabled on Freescale Book-E platforms. Any reason not to just make it unconditional ? That sort of config option tend to just confuse things and make bug reports harder to sort out Also you decrease your test coverage. Cheers, Ben. The bootloader have done a timebase sync. If we do not need KEXEC or HOTPLUG_CPU feature, it is unnecessary to do it again at boot time of kernel. I only compile the timebase sync routines when users enable KEXEC or HOTPLUG_CPU. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v6 1/5] powerpc/85xx: implement hardware timebase sync
On Fri, Jun 29, 2012 at 10:39:24AM -0500, Tabi Timur-B04825 wrote: On Tue, Jun 26, 2012 at 5:25 AM, Zhao Chenhui chenhui.z...@freescale.com wrote: Do hardware timebase sync. Firstly, stop all timebases, and transfer the timebase value of the boot core to the other core. Finally, start all timebases. Only apply to dual-core chips, such as MPC8572, P2020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- Changes for v6:  * added 85xx_TB_SYNC  * added isync() after set_tb()  * removed extra entries from mpc85xx_smp_guts_ids  arch/powerpc/include/asm/fsl_guts.h |   2 +  arch/powerpc/platforms/85xx/Kconfig |   5 ++  arch/powerpc/platforms/85xx/smp.c  |  84 +++  3 files changed, 91 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index ff42490..edb0cad 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -24,6 +24,7 @@  #include asm/mpic.h  #include asm/cacheflush.h  #include asm/dbell.h +#include asm/fsl_guts.h  #include sysdev/fsl_soc.h  #include sysdev/mpic.h @@ -42,6 +43,69 @@ extern void __early_start(void);  #define NUM_BOOT_ENTRY     8  #define SIZE_BOOT_ENTRY         (NUM_BOOT_ENTRY * sizeof(u32)) +#ifdef CONFIG_85xx_TB_SYNC +static struct ccsr_guts __iomem *guts; +static u64 timebase; +static int tb_req; +static int tb_valid; + +static void mpc85xx_timebase_freeze(int freeze) +{ +    unsigned int mask; 'mask' should be uint32_t OK. + +    if (!guts) +        return; This function should never be called if guts is NULL, so this check should be unnecessary. OK. + +    mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; +    if (freeze) +        setbits32(guts-devdisr, mask); +    else +        clrbits32(guts-devdisr, mask); + +    in_be32(guts-devdisr); +} + @@ -249,6 +323,16 @@ void __init mpc85xx_smp_init(void)         smp_85xx_ops.cause_ipi = doorbell_cause_ipi;     } +    np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); +    if (np) { +#ifdef CONFIG_85xx_TB_SYNC +        guts = of_iomap(np, 0); You need to test the return value of of_iomap(). smp_85xx_ops should be set only if guts is not NULL. Yes. Thanks. +        smp_85xx_ops.give_timebase = mpc85xx_give_timebase; +        smp_85xx_ops.take_timebase = mpc85xx_take_timebase; +#endif +        of_node_put(np); +    } +     smp_ops = smp_85xx_ops;  #ifdef CONFIG_KEXEC -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v6 1/5] powerpc/85xx: implement hardware timebase sync
On Thu, Jun 28, 2012 at 08:50:51PM +1000, Benjamin Herrenschmidt wrote: On Thu, 2012-06-28 at 11:38 +0800, Zhao Chenhui wrote: The bootloader have done a timebase sync. If we do not need KEXEC or HOTPLUG_CPU feature, it is unnecessary to do it again at boot time of kernel. I only compile the timebase sync routines when users enable KEXEC or HOTPLUG_CPU. Still, how much are you really saving ? Is it worth the added mess and loss of test coverage ? We have too many conditional stuff like that already. Cheers, Ben. OK. I will remove this config option. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v7 1/5] powerpc/85xx: implement hardware timebase sync
Do hardware timebase sync. Firstly, stop all timebases, and transfer the timebase value of the boot core to the other core. Finally, start all timebases. Only apply to dual-core chips, such as MPC8572, P2020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- v7: * removed CONFIG_85xx_TB_SYNC * incorporated Timur's comments arch/powerpc/include/asm/fsl_guts.h |2 + arch/powerpc/platforms/85xx/smp.c | 82 +++ 2 files changed, 84 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index aa4c488..dd5ba2c 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -48,6 +48,8 @@ struct ccsr_guts { __be32 dmuxcr;/* 0x.0068 - DMA Mux Control Register */ u8 res06c[0x70 - 0x6c]; __be32 devdisr;/* 0x.0070 - Device Disable Control */ +#define CCSR_GUTS_DEVDISR_TB1 0x1000 +#define CCSR_GUTS_DEVDISR_TB0 0x4000 __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ u8 res078[0x7c - 0x78]; __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index ff42490..2e65fe8 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -24,6 +24,7 @@ #include asm/mpic.h #include asm/cacheflush.h #include asm/dbell.h +#include asm/fsl_guts.h #include sysdev/fsl_soc.h #include sysdev/mpic.h @@ -42,6 +43,64 @@ extern void __early_start(void); #define NUM_BOOT_ENTRY 8 #define SIZE_BOOT_ENTRY(NUM_BOOT_ENTRY * sizeof(u32)) +static struct ccsr_guts __iomem *guts; +static u64 timebase; +static int tb_req; +static int tb_valid; + +static void mpc85xx_timebase_freeze(int freeze) +{ + uint32_t mask; + + mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; + if (freeze) + setbits32(guts-devdisr, mask); + else + clrbits32(guts-devdisr, mask); + + in_be32(guts-devdisr); +} + +static void mpc85xx_give_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + while (!tb_req) + barrier(); + tb_req = 0; + + mpc85xx_timebase_freeze(1); + timebase = get_tb(); + mb(); + tb_valid = 1; + + while (tb_valid) + barrier(); + + mpc85xx_timebase_freeze(0); + + local_irq_restore(flags); +} + +static void mpc85xx_take_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + tb_req = 1; + while (!tb_valid) + barrier(); + + set_tb(timebase 32, timebase 0x); + isync(); + tb_valid = 0; + + local_irq_restore(flags); +} + static int __init smp_85xx_kick_cpu(int nr) { @@ -228,6 +287,16 @@ smp_85xx_setup_cpu(int cpu_nr) doorbell_setup_this_cpu(); } +static const struct of_device_id mpc85xx_smp_guts_ids[] = { + { .compatible = fsl,mpc8572-guts, }, + { .compatible = fsl,p1020-guts, }, + { .compatible = fsl,p1021-guts, }, + { .compatible = fsl,p1022-guts, }, + { .compatible = fsl,p1023-guts, }, + { .compatible = fsl,p2020-guts, }, + {}, +}; + void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -249,6 +318,19 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.cause_ipi = doorbell_cause_ipi; } + np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); + if (np) { + guts = of_iomap(np, 0); + of_node_put(np); + if (!guts) { + pr_err(%s: Could not map guts node address\n, + __func__); + return; + } + smp_85xx_ops.give_timebase = mpc85xx_give_timebase; + smp_85xx_ops.take_timebase = mpc85xx_take_timebase; + } + smp_ops = smp_85xx_ops; #ifdef CONFIG_KEXEC -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v7 2/5] powerpc/85xx: add HOTPLUG_CPU support
From: Li Yang le...@freescale.com Add support to disable and re-enable individual cores at runtime on MPC85xx/QorIQ SMP machines. Currently support e500v1/e500v2 core. MPC85xx machines use ePAPR spin-table in boot page for CPU kick-off. This patch uses the boot page from bootloader to boot core at runtime. It supports 32-bit and 36-bit physical address. Add generic_set_cpu_up() to set cpu_state as CPU_UP_PREPARE in kick_cpu(). Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- v7: * removed CONFIG_85xx_TB_SYNC no change to the rest of the patch set arch/powerpc/Kconfig |6 +- arch/powerpc/include/asm/cacheflush.h |2 + arch/powerpc/include/asm/smp.h|2 + arch/powerpc/kernel/head_fsl_booke.S | 28 +++ arch/powerpc/kernel/smp.c | 10 +++ arch/powerpc/platforms/85xx/smp.c | 137 - 6 files changed, 146 insertions(+), 39 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 38786c8..d6bacbe 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -220,7 +220,8 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ - (PPC_85xx !SMP) || PPC_86xx || PPC_PSERIES || 44x || 40x + (PPC_85xx !PPC_E500MC) || PPC_86xx || PPC_PSERIES \ + || 44x || 40x config PPC_DCR_NATIVE bool @@ -331,7 +332,8 @@ config SWIOTLB config HOTPLUG_CPU bool Support for enabling/disabling CPUs - depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || PPC_PMAC || PPC_POWERNV) + depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || \ + PPC_PMAC || PPC_POWERNV || (PPC_85xx !PPC_E500MC)) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index ab9e402..b843e35 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -30,6 +30,8 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping)do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) +extern void __flush_disable_L1(void); + extern void __flush_icache_range(unsigned long, unsigned long); static inline void flush_icache_range(unsigned long start, unsigned long stop) { diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index ebc24dc..e807e9d 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -65,6 +65,7 @@ int generic_cpu_disable(void); void generic_cpu_die(unsigned int cpu); void generic_mach_cpu_die(void); void generic_set_cpu_dead(unsigned int cpu); +void generic_set_cpu_up(unsigned int cpu); int generic_check_cpu_restart(unsigned int cpu); #endif @@ -190,6 +191,7 @@ extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; extern char __secondary_hold; +extern void __early_start(void); #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index de80e0f..be0261b 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -996,6 +996,34 @@ _GLOBAL(flush_dcache_L1) blr +/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ +_GLOBAL(__flush_disable_L1) + mflrr10 + bl flush_dcache_L1 /* Flush L1 d-cache */ + mtlrr10 + + mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + msync + isync + mtspr SPRN_L1CSR0, r4 + isync + +1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ + andi. r4, r4, 2 + bne 1b + + mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + mtspr SPRN_L1CSR1, r4 + isync + + blr + #ifdef CONFIG_SMP /* When we get here, r24 needs to hold the CPU # */ .globl __secondary_start diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index d9f9441..e0ffe03 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -423,6 +423,16 @@ void generic_set_cpu_dead(unsigned int cpu) per_cpu(cpu_state, cpu) = CPU_DEAD; } +/* + * The cpu_state should be set to CPU_UP_PREPARE in kick_cpu(), otherwise + * the cpu_state is always CPU_DEAD after calling generic_set_cpu_dead(), + * which makes the delay in generic_cpu_die() not happen. + */ +void generic_set_cpu_up(unsigned int cpu) +{ + per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; +} + int
Re: [PATCH v7 1/5] powerpc/85xx: implement hardware timebase sync
On Tue, Jul 03, 2012 at 07:46:24AM -0500, Tabi Timur-B04825 wrote: On Tue, Jul 3, 2012 at 5:21 AM, Zhao Chenhui chenhui.z...@freescale.com wrote: + np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); + if (np) { + guts = of_iomap(np, 0); + of_node_put(np); + if (!guts) { + pr_err(%s: Could not map guts node address\n, + __func__); + return; + } + smp_85xx_ops.give_timebase = mpc85xx_give_timebase; + smp_85xx_ops.take_timebase = mpc85xx_take_timebase; + } I had this in mind: guts = of_iomap(np, 0); of_node_put(np); if (guts) { smp_85xx_ops.give_timebase = mpc85xx_give_timebase; smp_85xx_ops.take_timebase = mpc85xx_take_timebase; } else { pr_err(%s: Could not map guts node address\n, __func__); } That way, a missing GUTS node does not break everything. If the guts variable is NULL, it indicates there is error in dts or kernel. We should fix the error, rather than ignore it. Moreover, if smp_85xx_ops.give/take_timebase is NULL, kernel can not do the timebase sync. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v7 1/5] powerpc/85xx: implement hardware timebase sync
On Tue, Jul 03, 2012 at 10:17:12PM -0500, Tabi Timur-B04825 wrote: Zhao Chenhui wrote: If the guts variable is NULL, it indicates there is error in dts or kernel. We should fix the error, rather than ignore it. And that's why there's a warning message. Crashing the kernel is not going to fix anything. This error likely crashes the kenel somewhere. Moreover, if smp_85xx_ops.give/take_timebase is NULL, kernel can not do the timebase sync. Is that necessary for the kernel to boot? No. But in the cpu hotplug context, we need do the timebase sync. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v7 1/5] powerpc/85xx: implement hardware timebase sync
On Wed, Jul 04, 2012 at 10:19:54AM -0500, Tabi Timur-B04825 wrote: Zhao Chenhui wrote: On Tue, Jul 03, 2012 at 10:17:12PM -0500, Tabi Timur-B04825 wrote: Zhao Chenhui wrote: If the guts variable is NULL, it indicates there is error in dts or kernel. We should fix the error, rather than ignore it. And that's why there's a warning message. Crashing the kernel is not going to fix anything. This error likely crashes the kenel somewhere. Can you test this, please? The point I'm trying to make is that it's wrong to intentionally halt the kernel unless you're sure that it's the best option. A missing device tree node is supposed to only disable a given feature, not break everything. I think there is some misunderstanding here. np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); if (np) { guts = of_iomap(np, 0); of_node_put(np); if (!guts) { pr_err(%s: Could not map guts node address\n, __func__); return; } smp_85xx_ops.give_timebase = mpc85xx_give_timebase; smp_85xx_ops.take_timebase = mpc85xx_take_timebase; } If the guts node is missing, this code snippet will be skipped. If the guts node is existed, the return value of of_iomap(), namely guts, will be tested. If it is NULL, it shows that there is error in dts, or the ioremap() in of_iomap() failed. I think these errors are fatal errors, so I print an error info and return. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v8 0/7] power management patch set
Changes for v8: * Separated the cpu hotplug patch into three patches, as follows [PATCH v8 1/7] powerpc/smp: use a struct epapr_spin_table to replace macros [PATCH v8 2/7] powerpc/smp: add generic_set_cpu_up() to set cpu_state as CPU_UP_PREPARE [PATCH v8 4/7] powerpc/85xx: add HOTPLUG_CPU support * Replaced magic numbers with macros in [PATCH 5/7] powerpc/85xx: add sleep and deep sleep support * no change to the rest of the patch set ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v8 1/7] powerpc/smp: use a struct epapr_spin_table to replace macros
Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/platforms/85xx/smp.c | 46 ++-- 1 files changed, 23 insertions(+), 23 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index ff42490..4827709 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -2,7 +2,7 @@ * Author: Andy Fleming aflem...@freescale.com *Kumar Gala ga...@kernel.crashing.org * - * Copyright 2006-2008, 2011 Freescale Semiconductor Inc. + * Copyright 2006-2008, 2011-2012 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 @@ -17,6 +17,7 @@ #include linux/of.h #include linux/kexec.h #include linux/highmem.h +#include linux/cpu.h #include asm/machdep.h #include asm/pgtable.h @@ -31,23 +32,21 @@ extern void __early_start(void); -#define BOOT_ENTRY_ADDR_UPPER 0 -#define BOOT_ENTRY_ADDR_LOWER 1 -#define BOOT_ENTRY_R3_UPPER2 -#define BOOT_ENTRY_R3_LOWER3 -#define BOOT_ENTRY_RESV4 -#define BOOT_ENTRY_PIR 5 -#define BOOT_ENTRY_R6_UPPER6 -#define BOOT_ENTRY_R6_LOWER7 -#define NUM_BOOT_ENTRY 8 -#define SIZE_BOOT_ENTRY(NUM_BOOT_ENTRY * sizeof(u32)) +struct epapr_spin_table { + u32 addr_h; + u32 addr_l; + u32 r3_h; + u32 r3_l; + u32 reserved; + u32 pir; +}; static int __init smp_85xx_kick_cpu(int nr) { unsigned long flags; const u64 *cpu_rel_addr; - __iomem u32 *bptr_vaddr; + __iomem struct epapr_spin_table *spin_table; struct device_node *np; int n = 0, hw_cpu = get_hard_smp_processor_id(nr); int ioremappable; @@ -75,19 +74,20 @@ smp_85xx_kick_cpu(int nr) /* Map the spin table */ if (ioremappable) - bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); + spin_table = ioremap(*cpu_rel_addr, + sizeof(struct epapr_spin_table)); else - bptr_vaddr = phys_to_virt(*cpu_rel_addr); + spin_table = phys_to_virt(*cpu_rel_addr); local_irq_save(flags); - out_be32(bptr_vaddr + BOOT_ENTRY_PIR, hw_cpu); + out_be32(spin_table-pir, hw_cpu); #ifdef CONFIG_PPC32 - out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); + out_be32(spin_table-addr_l, __pa(__early_start)); if (!ioremappable) - flush_dcache_range((ulong)bptr_vaddr, - (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY)); + flush_dcache_range((ulong)spin_table, + (ulong)spin_table + sizeof(struct epapr_spin_table)); /* Wait a bit for the CPU to ack. */ while ((__secondary_hold_acknowledge != hw_cpu) (++n 1000)) @@ -95,18 +95,18 @@ smp_85xx_kick_cpu(int nr) #else smp_generic_kick_cpu(nr); - out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER), - __pa((u64)*((unsigned long long *) generic_secondary_smp_init))); + out_be64((u64 *)(spin_table-addr_h), + __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); if (!ioremappable) - flush_dcache_range((ulong)bptr_vaddr, - (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY)); + flush_dcache_range((ulong)spin_table, + (ulong)spin_table + sizeof(struct epapr_spin_table)); #endif local_irq_restore(flags); if (ioremappable) - iounmap(bptr_vaddr); + iounmap(spin_table); pr_debug(waited %d msecs for CPU #%d.\n, n, nr); -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v8 3/7] powerpc/85xx: implement hardware timebase sync
Do hardware timebase sync. Firstly, stop all timebases, and transfer the timebase value of the boot core to the other core. Finally, start all timebases. Only apply to dual-core chips, such as MPC8572, P2020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/include/asm/fsl_guts.h |2 + arch/powerpc/platforms/85xx/smp.c | 82 +++ 2 files changed, 84 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index aa4c488..dd5ba2c 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -48,6 +48,8 @@ struct ccsr_guts { __be32 dmuxcr;/* 0x.0068 - DMA Mux Control Register */ u8 res06c[0x70 - 0x6c]; __be32 devdisr;/* 0x.0070 - Device Disable Control */ +#define CCSR_GUTS_DEVDISR_TB1 0x1000 +#define CCSR_GUTS_DEVDISR_TB0 0x4000 __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ u8 res078[0x7c - 0x78]; __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 4827709..7ed52a6 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -25,6 +25,7 @@ #include asm/mpic.h #include asm/cacheflush.h #include asm/dbell.h +#include asm/fsl_guts.h #include sysdev/fsl_soc.h #include sysdev/mpic.h @@ -41,6 +42,64 @@ struct epapr_spin_table { u32 pir; }; +static struct ccsr_guts __iomem *guts; +static u64 timebase; +static int tb_req; +static int tb_valid; + +static void mpc85xx_timebase_freeze(int freeze) +{ + uint32_t mask; + + mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; + if (freeze) + setbits32(guts-devdisr, mask); + else + clrbits32(guts-devdisr, mask); + + in_be32(guts-devdisr); +} + +static void mpc85xx_give_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + while (!tb_req) + barrier(); + tb_req = 0; + + mpc85xx_timebase_freeze(1); + timebase = get_tb(); + mb(); + tb_valid = 1; + + while (tb_valid) + barrier(); + + mpc85xx_timebase_freeze(0); + + local_irq_restore(flags); +} + +static void mpc85xx_take_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + tb_req = 1; + while (!tb_valid) + barrier(); + + set_tb(timebase 32, timebase 0x); + isync(); + tb_valid = 0; + + local_irq_restore(flags); +} + static int __init smp_85xx_kick_cpu(int nr) { @@ -228,6 +287,16 @@ smp_85xx_setup_cpu(int cpu_nr) doorbell_setup_this_cpu(); } +static const struct of_device_id mpc85xx_smp_guts_ids[] = { + { .compatible = fsl,mpc8572-guts, }, + { .compatible = fsl,p1020-guts, }, + { .compatible = fsl,p1021-guts, }, + { .compatible = fsl,p1022-guts, }, + { .compatible = fsl,p1023-guts, }, + { .compatible = fsl,p2020-guts, }, + {}, +}; + void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -249,6 +318,19 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.cause_ipi = doorbell_cause_ipi; } + np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); + if (np) { + guts = of_iomap(np, 0); + of_node_put(np); + if (!guts) { + pr_err(%s: Could not map guts node address\n, + __func__); + return; + } + smp_85xx_ops.give_timebase = mpc85xx_give_timebase; + smp_85xx_ops.take_timebase = mpc85xx_take_timebase; + } + smp_ops = smp_85xx_ops; #ifdef CONFIG_KEXEC -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v8 2/7] powerpc/smp: add generic_set_cpu_up() to set cpu_state as CPU_UP_PREPARE
In the case of cpu hotplug, the cpu_state should be set to CPU_UP_PREPARE when kicking cpu. Otherwise, the cpu_state is always CPU_DEAD after calling generic_set_cpu_dead(), which makes the delay in generic_cpu_die() not happen. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/include/asm/smp.h |1 + arch/powerpc/kernel/smp.c | 12 +++- 2 files changed, 12 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index ebc24dc..ce8e2bd 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -65,6 +65,7 @@ int generic_cpu_disable(void); void generic_cpu_die(unsigned int cpu); void generic_mach_cpu_die(void); void generic_set_cpu_dead(unsigned int cpu); +void generic_set_cpu_up(unsigned int cpu); int generic_check_cpu_restart(unsigned int cpu); #endif diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 0321007..fecb038 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -102,7 +102,7 @@ int __devinit smp_generic_kick_cpu(int nr) * Ok it's not there, so it might be soft-unplugged, let's * try to bring it back */ - per_cpu(cpu_state, nr) = CPU_UP_PREPARE; + generic_set_cpu_up(nr); smp_wmb(); smp_send_reschedule(nr); #endif /* CONFIG_HOTPLUG_CPU */ @@ -406,6 +406,16 @@ void generic_set_cpu_dead(unsigned int cpu) per_cpu(cpu_state, cpu) = CPU_DEAD; } +/* + * The cpu_state should be set to CPU_UP_PREPARE in kick_cpu(), otherwise + * the cpu_state is always CPU_DEAD after calling generic_set_cpu_dead(), + * which makes the delay in generic_cpu_die() not happen. + */ +void generic_set_cpu_up(unsigned int cpu) +{ + per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; +} + int generic_check_cpu_restart(unsigned int cpu) { return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v8 4/7] powerpc/85xx: add HOTPLUG_CPU support
Add support to disable and re-enable individual cores at runtime on MPC85xx/QorIQ SMP machines. Currently support e500v1/e500v2 core. MPC85xx machines use ePAPR spin-table in boot page for CPU kick-off. This patch uses the boot page from bootloader to boot core at runtime. It supports 32-bit and 36-bit physical address. Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/Kconfig |6 ++- arch/powerpc/include/asm/cacheflush.h |2 + arch/powerpc/include/asm/smp.h|1 + arch/powerpc/kernel/head_fsl_booke.S | 28 ++ arch/powerpc/platforms/85xx/smp.c | 90 - 5 files changed, 112 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9a5d3cd..a7c6914 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -213,7 +213,8 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ - (PPC_85xx !SMP) || PPC_86xx || PPC_PSERIES || 44x || 40x + (PPC_85xx !PPC_E500MC) || PPC_86xx || PPC_PSERIES \ + || 44x || 40x config PPC_DCR_NATIVE bool @@ -323,7 +324,8 @@ config SWIOTLB config HOTPLUG_CPU bool Support for enabling/disabling CPUs - depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || PPC_PMAC || PPC_POWERNV) + depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || \ + PPC_PMAC || PPC_POWERNV || (PPC_85xx !PPC_E500MC)) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index ab9e402..b843e35 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -30,6 +30,8 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping)do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) +extern void __flush_disable_L1(void); + extern void __flush_icache_range(unsigned long, unsigned long); static inline void flush_icache_range(unsigned long start, unsigned long stop) { diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index ce8e2bd..e807e9d 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -191,6 +191,7 @@ extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; extern char __secondary_hold; +extern void __early_start(void); #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 0f59863..b221541 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -1043,6 +1043,34 @@ _GLOBAL(flush_dcache_L1) blr +/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ +_GLOBAL(__flush_disable_L1) + mflrr10 + bl flush_dcache_L1 /* Flush L1 d-cache */ + mtlrr10 + + mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + msync + isync + mtspr SPRN_L1CSR0, r4 + isync + +1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ + andi. r4, r4, 2 + bne 1b + + mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + mtspr SPRN_L1CSR1, r4 + isync + + blr + #ifdef CONFIG_SMP /* When we get here, r24 needs to hold the CPU # */ .globl __secondary_start diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 7ed52a6..6fcfa12 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -31,8 +31,6 @@ #include sysdev/mpic.h #include smp.h -extern void __early_start(void); - struct epapr_spin_table { u32 addr_h; u32 addr_l; @@ -100,15 +98,45 @@ static void mpc85xx_take_timebase(void) local_irq_restore(flags); } -static int __init -smp_85xx_kick_cpu(int nr) +#ifdef CONFIG_HOTPLUG_CPU +static void __cpuinit smp_85xx_mach_cpu_die(void) +{ + unsigned int cpu = smp_processor_id(); + u32 tmp; + + local_irq_disable(); + idle_task_exit(); + generic_set_cpu_dead(cpu); + mb(); + + mtspr(SPRN_TCR, 0); + + __flush_disable_L1(); + tmp = (mfspr(SPRN_HID0) ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP; + mtspr(SPRN_HID0, tmp); + isync(); + + /* Enter NAP mode. */ + tmp = mfmsr(); + tmp |= MSR_WE; + mb(); + mtmsr(tmp); + isync(); + + while (1
[PATCH v8 5/7] 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: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Cc: Scott Wood scottw...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/cacheflush.h |2 + arch/powerpc/kernel/Makefile |3 + arch/powerpc/kernel/l2cache_85xx.S| 56 +++ arch/powerpc/platforms/85xx/Makefile |2 +- arch/powerpc/platforms/85xx/sleep.S | 621 + arch/powerpc/sysdev/fsl_pmc.c | 98 +- arch/powerpc/sysdev/fsl_soc.h |5 + 8 files changed, 769 insertions(+), 20 deletions(-) create mode 100644 arch/powerpc/kernel/l2cache_85xx.S create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a7c6914..9d6de82 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -665,7 +665,7 @@ config FSL_PCI config FSL_PMC bool default y - depends on SUSPEND (PPC_85xx || PPC_86xx) + depends on SUSPEND (PPC_85xx || PPC_86xx) !PPC_E500MC help Freescale MPC85xx/MPC86xx power management controller support (suspend/resume). For MPC83xx see platforms/83xx/suspend.c diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index b843e35..6c5f1c2 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -58,6 +58,8 @@ extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); #endif +extern void flush_dcache_L1(void); + #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ memcpy(dst, src, len); \ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 83afacd..0ddef24 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -64,6 +64,9 @@ obj-$(CONFIG_FA_DUMP) += fadump.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o endif +ifneq ($(CONFIG_PPC_E500MC),y) +obj-$(CONFIG_PPC_85xx) += l2cache_85xx.o +endif obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o diff --git a/arch/powerpc/kernel/l2cache_85xx.S b/arch/powerpc/kernel/l2cache_85xx.S new file mode 100644 index 000..e920d69 --- /dev/null +++ b/arch/powerpc/kernel/l2cache_85xx.S @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009-2012 Freescale Semiconductor, Inc. All rights reserved. + * Scott Wood scottw...@freescale.com + * Dave Liu dave...@freescale.com + * implement the L2 cache operations of e500 based L2 controller + * + * 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/reg.h +#include asm/cputable.h +#include asm/ppc_asm.h +#include asm/asm-offsets.h + +#define L2CTL_L2E 0x8000 +#define L2CTL_L2I 0x4000 + + .section .text + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(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, L2CTL_L2E | L2CTL_L2I + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, L2CTL_L2I@h + bne 1b + mbar + + blr + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(invalidate_enable_L2) + mbar + isync + lwz r4, 0(r3) + li r5, 3 + rlwimi r4, r5, 30, L2CTL_L2E | L2CTL_L2I + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, L2CTL_L2I@h + bne 1b
[PATCH v8 6/7] fsl_pmc: Add API to enable device as wakeup event source
Add APIs for setting wakeup source and lossless Ethernet in low power modes. These APIs can be used by wake-on-packet feature. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/sysdev/fsl_pmc.c | 77 - arch/powerpc/sysdev/fsl_soc.h | 12 ++ 2 files changed, 88 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 45718c5..b6c8c8f 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -38,6 +38,7 @@ struct pmc_regs { __be32 powmgtcsr; #define POWMGTCSR_SLP 0x0002 #define POWMGTCSR_DPSLP0x0010 +#define POWMGTCSR_LOSSLESS 0x0040 __be32 res3[2]; /* 0xe008c: Power management clock disable register */ __be32 pmcdr; @@ -48,6 +49,77 @@ static unsigned int pmc_flag; #define PMC_SLEEP 0x1 #define PMC_DEEP_SLEEP 0x2 +#define PMC_LOSSLESS 0x4 + +#define PMCDR_MASK_INIT0x00e008e0 + +/** + * mpc85xx_pmc_set_wake - enable devices as wakeup event source + * @dev: a device affected + * @enable: True to enable event generation; false to disable + * + * This enables the device as a wakeup event source, or disables it. + * + * RETURN VALUE: + * 0 is returned on success. + * -EINVAL is returned if device is not supposed to wake up the system. + * -ENODEV is returned if PMC is unavailable. + * Error code depending on the platform is returned if both the platform and + * the native mechanism fail to enable the generation of wake-up events + */ +int mpc85xx_pmc_set_wake(struct device *dev, bool enable) +{ + int ret = 0; + struct device_node *clk_np; + const u32 *prop; + u32 pmcdr_mask; + + if (!pmc_regs) { + pr_err(%s: PMC is unavailable\n, __func__); + return -ENODEV; + } + + if (enable !device_may_wakeup(dev)) + return -EINVAL; + + clk_np = of_parse_phandle(dev-of_node, fsl,pmc-handle, 0); + if (!clk_np) + return -EINVAL; + + prop = of_get_property(clk_np, fsl,pmcdr-mask, NULL); + if (!prop) { + ret = -EINVAL; + goto out; + } + pmcdr_mask = be32_to_cpup(prop); + + if (enable) + /* clear to enable clock in low power mode */ + clrbits32(pmc_regs-pmcdr, pmcdr_mask); + else + setbits32(pmc_regs-pmcdr, pmcdr_mask); + +out: + of_node_put(clk_np); + return ret; +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_wake); + +/** + * mpc85xx_pmc_set_lossless_ethernet - enable lossless ethernet + * in (deep) sleep mode + * @enable: True to enable event generation; false to disable + */ +void mpc85xx_pmc_set_lossless_ethernet(int enable) +{ + if (pmc_flag PMC_LOSSLESS) { + if (enable) + setbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + else + clrbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + } +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_lossless_ethernet); static int pmc_suspend_enter(suspend_state_t state) { @@ -123,7 +195,10 @@ static int pmc_probe(struct platform_device *pdev) pmc_flag |= PMC_DEEP_SLEEP; if (of_device_is_compatible(np, fsl,p1022-pmc)) - pmc_flag |= PMC_DEEP_SLEEP; + pmc_flag |= PMC_DEEP_SLEEP | PMC_LOSSLESS; + + /* Init the Power Management Clock Disable Register. */ + setbits32(pmc_regs-pmcdr, PMCDR_MASK_INIT); suspend_set_ops(pmc_suspend_ops); diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 11d9f94..b1510ef 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -3,6 +3,7 @@ #ifdef __KERNEL__ #include asm/mmu.h +#include linux/platform_device.h struct spi_device; @@ -21,6 +22,17 @@ struct device_node; extern void fsl_rstcr_restart(char *cmd); +#ifdef CONFIG_FSL_PMC +extern int mpc85xx_pmc_set_wake(struct device *dev, bool enable); +extern void mpc85xx_pmc_set_lossless_ethernet(int enable); +#else +static inline int mpc85xx_pmc_set_wake(struct device *dev, bool enable) +{ + return -ENODEV; +} +#define mpc85xx_pmc_set_lossless_ethernet(enable) do { } while (0) +#endif + #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) /* The different ports that the DIU can be connected to */ -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v8 7/7] powerpc/85xx: add support to JOG feature using cpufreq interface
Some 85xx silicons like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a atomic counter to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum. Subsequent revisions of MPC8536 have corrected the erratum. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com CC: Scott Wood scottw...@freescale.com --- arch/powerpc/platforms/85xx/Makefile |1 + arch/powerpc/platforms/85xx/cpufreq-jog.c | 388 + arch/powerpc/platforms/Kconfig| 11 + arch/powerpc/sysdev/fsl_pmc.c |3 + arch/powerpc/sysdev/fsl_soc.h |2 + include/linux/cpu.h |4 + 6 files changed, 409 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/cpufreq-jog.c diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 405ab79..901cdd5 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_SMP) += smp.o obj-y += common.o sleep.o +obj-$(CONFIG_MPC85xx_CPUFREQ) += cpufreq-jog.o obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o diff --git a/arch/powerpc/platforms/85xx/cpufreq-jog.c b/arch/powerpc/platforms/85xx/cpufreq-jog.c new file mode 100644 index 000..ccc0c33 --- /dev/null +++ b/arch/powerpc/platforms/85xx/cpufreq-jog.c @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2008-2012 Freescale Semiconductor, Inc. + * Author: Dave Liu dave...@freescale.com + * Modifier: Chenhui Zhao chenhui.z...@freescale.com + * + * The cpufreq driver is for Freescale 85xx processor, + * based on arch/powerpc/platforms/cell/cbe_cpufreq.c + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 + * Christian Krafft kra...@de.ibm.com + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h +#include linux/cpufreq.h +#include linux/of_platform.h +#include linux/suspend.h +#include linux/cpu.h + +#include asm/prom.h +#include asm/time.h +#include asm/reg.h +#include asm/io.h +#include asm/machdep.h +#include asm/smp.h + +#include sysdev/fsl_soc.h + +static DEFINE_MUTEX(mpc85xx_switch_mutex); +static void __iomem *guts; + +static u32 sysfreq; +static unsigned int max_pll[2]; +static atomic_t in_jog_process; +static struct cpufreq_frequency_table *mpc85xx_freqs; +static int (*set_pll)(unsigned int cpu, unsigned int pll); + +static struct cpufreq_frequency_table mpc8536_freqs_table[] = { + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +static struct cpufreq_frequency_table p1022_freqs_table[] = { + {2, 0}, + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +#define FREQ_500MHz5 +#define FREQ_800MHz8 + +#define CORE_RATIO_STRIDE 8 +#define CORE_RATIO_MASK0x3f +#define CORE_RATIO_SHIFT 16 + +#define PORPLLSR 0x0 /* Power-On Reset PLL ratio status register */ + +#define PMJCR 0x7c/* Power Management Jog Control Register */ +#define PMJCR_CORE0_SPD0x1000 +#define PMJCR_CORE_SPD 0x2000 + +#define POWMGTCSR 0x80 /* Power management control and status register */ +#define POWMGTCSR_JOG 0x0020 +#define POWMGTCSR_INT_MASK 0x0f00 + +static void spin_while_jogging(void *dummy
[PATCH] mpc85xx_defconfig: add IDE support for MPC85xxCDS
Add IDE support for MPC85xxCDS. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/configs/mpc85xx_defconfig |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index 03ee911..45eda33 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -105,6 +105,8 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=y +CONFIG_IDE=y +CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/smp: Do not disable IPI interrupts during suspend
During suspend, all interrupts including IPI will be disabled. In this case, the suspend process will hang in SMP. To prevent this, pass the flag IRQF_NO_SUSPEND when requesting IPI irq. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/kernel/smp.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index fecb038..d26bbf8 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -171,7 +171,7 @@ int smp_request_message_ipi(int virq, int msg) } #endif err = request_irq(virq, smp_ipi_action[msg], - IRQF_PERCPU | IRQF_NO_THREAD, + IRQF_PERCPU | IRQF_NO_THREAD | IRQF_NO_SUSPEND, smp_ipi_name[msg], 0); WARN(err 0, unable to request_irq %d for %s (rc %d)\n, virq, smp_ipi_name[msg], err); -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] pm: add power node to dts
The Power Management device tree stub indicated that the platform supports Power Management feature. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi | 14 ++- arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/p1010si-post.dtsi |8 arch/powerpc/boot/dts/fsl/p1020si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1021si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1022si-post.dtsi | 11 -- arch/powerpc/boot/dts/fsl/p2020si-post.dtsi | 14 +++ arch/powerpc/boot/dts/fsl/pq3-power.dtsi | 48 + 10 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/pq3-power.dtsi diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi index c8b2daa..900f117 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi @@ -199,6 +199,10 @@ /include/ pq3-dma-0.dtsi /include/ pq3-etsec1-0.dtsi + enet0: ethernet@24000 { + fsl,wake-on-filer; + fsl,pmc-handle = etsec1_clk; + }; /include/ pq3-etsec1-timer-0.dtsi usb@22000 { @@ -222,9 +226,10 @@ }; /include/ pq3-etsec1-2.dtsi - - ethernet@26000 { + enet2: ethernet@26000 { cell-index = 1; + fsl,wake-on-filer; + fsl,pmc-handle = etsec3_clk; }; usb@2b000 { @@ -249,4 +254,9 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi + power@e0070 { + compatible = fsl,mpc8536-pmc, fsl,mpc8548-pmc; + }; }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi index b68eb11..ea7416a 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi @@ -188,4 +188,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi index 579d76c..dddb737 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi @@ -156,4 +156,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi index d44e25a..7313351 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi @@ -193,4 +193,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi index 0bde9ee..108daa5 100644 --- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -171,6 +171,8 @@ /include/ pq3-etsec2-0.dtsi enet0: ethernet@b { + fsl,pmc-handle = etsec1_clk; + queue-group@b { fsl,rx-bit-map = 0xff; fsl,tx-bit-map = 0xff; @@ -179,6 +181,8 @@ /include/ pq3-etsec2-1.dtsi enet1: ethernet@b1000 { + fsl,pmc-handle = etsec2_clk; + queue-group@b1000 { fsl,rx-bit-map = 0xff; fsl,tx-bit-map = 0xff; @@ -187,6 +191,8 @@ /include/ pq3-etsec2-2.dtsi enet2: ethernet@b2000 { + fsl,pmc-handle = etsec3_clk; + queue-group@b2000 { fsl,rx-bit-map = 0xff; fsl,tx-bit-map = 0xff; @@ -199,4 +205,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi index 68cc5e7..410e6e5 100644 --- a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi @@ -162,14 +162,17 @@ /include/ pq3-etsec2-0.dtsi enet0: enet0_grp2: ethernet@b { + fsl,pmc-handle = etsec1_clk; }; /include/ pq3-etsec2-1.dtsi enet1: enet1_grp2: ethernet@b1000 { + fsl,pmc-handle = etsec2_clk; }; /include/ pq3-etsec2-2.dtsi enet2: enet2_grp2: ethernet@b2000 { + fsl,pmc-handle = etsec3_clk; }; global-utilities@e { @@ -177,6 +180,8 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; /include/ pq3-etsec2-grp2-0.dtsi
Re: [PATCH] mpc85xx_defconfig: add IDE support for MPC85xxCDS
On Fri, Jul 20, 2012 at 03:09:00PM +0100, Alan Cox wrote: On Fri, 20 Jul 2012 20:45:25 +0800 Zhao Chenhui chenhui.z...@freescale.com wrote: Add IDE support for MPC85xxCDS. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/configs/mpc85xx_defconfig |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index 03ee911..45eda33 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -105,6 +105,8 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=y +CONFIG_IDE=y +CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_IDE is obsolete we shouldn't be adding it to anything as it will eventually go away. Please use the ATA drivers. Thanks. I will replace it with the ATA driver. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/smp: Do not disable IPI interrupts during suspend
On Sat, Jul 28, 2012 at 08:20:31AM +1000, Benjamin Herrenschmidt wrote: On Fri, 2012-07-27 at 16:58 -0500, Kumar Gala wrote: On Jul 20, 2012, at 7:47 AM, Zhao Chenhui wrote: During suspend, all interrupts including IPI will be disabled. In this case, the suspend process will hang in SMP. To prevent this, pass the flag IRQF_NO_SUSPEND when requesting IPI irq. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/kernel/smp.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) BenH, Can you ack? No I'll merge it but not until it's been in next for a bit unless you have some strong emergency there, it's on my mental list of things to shovel into next after rc1. Curiosity: didn't we use to disable all non-boot CPUs on suspend ? Cheers, Ben. Yes, we disabled all non-boot CPUs on suspend by calling disable_nonboot_cpus(). The disable_nonboot_cpus() needs IPIs to work. But prior to calling disable_nonboot_cpus(), the IPIs are disabled in dpm_suspend_noirq(). -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v8 5/7] powerpc/85xx: add sleep and deep sleep support
On Tue, Jul 31, 2012 at 09:15:33AM -0500, Kumar Gala wrote: On Jul 20, 2012, at 7:42 AM, Zhao Chenhui wrote: 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: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Cc: Scott Wood scottw...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/cacheflush.h |2 + arch/powerpc/kernel/Makefile |3 + arch/powerpc/kernel/l2cache_85xx.S| 56 +++ arch/powerpc/platforms/85xx/Makefile |2 +- arch/powerpc/platforms/85xx/sleep.S | 621 + arch/powerpc/sysdev/fsl_pmc.c | 98 +- arch/powerpc/sysdev/fsl_soc.h |5 + 8 files changed, 769 insertions(+), 20 deletions(-) create mode 100644 arch/powerpc/kernel/l2cache_85xx.S create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a7c6914..9d6de82 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -665,7 +665,7 @@ config FSL_PCI config FSL_PMC bool default y - depends on SUSPEND (PPC_85xx || PPC_86xx) + depends on SUSPEND (PPC_85xx || PPC_86xx) !PPC_E500MC help Freescale MPC85xx/MPC86xx power management controller support (suspend/resume). For MPC83xx see platforms/83xx/suspend.c diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index b843e35..6c5f1c2 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -58,6 +58,8 @@ extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); #endif +extern void flush_dcache_L1(void); + #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ memcpy(dst, src, len); \ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 83afacd..0ddef24 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -64,6 +64,9 @@ obj-$(CONFIG_FA_DUMP) += fadump.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o endif +ifneq ($(CONFIG_PPC_E500MC),y) +obj-$(CONFIG_PPC_85xx) += l2cache_85xx.o +endif why do we need this, beyond reduce code size on an e500mc kernel build? If so why isn't 85xx/sleep.S doing the same thing? - k Yes, it is a little awkward. I have an idea to put e500/e500mc/e5500/e6500 related flush cache routines into this file, and rename it to cache_fsl_booke.S. As for 85xx/sleep.S, it is used by fsl_pmc.c. I will use CONFIG_FSL_PMC to guard it. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/4] 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: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Cc: Scott Wood scottw...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/cacheflush.h |2 + arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/cache_fsl.S | 57 +++ arch/powerpc/platforms/85xx/Makefile |1 + arch/powerpc/platforms/85xx/sleep.S | 621 + arch/powerpc/sysdev/fsl_pmc.c | 98 +- arch/powerpc/sysdev/fsl_soc.h |5 + 8 files changed, 768 insertions(+), 19 deletions(-) create mode 100644 arch/powerpc/kernel/cache_fsl.S create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d894069..d7b0517 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -667,7 +667,7 @@ config FSL_PCI config FSL_PMC bool default y - depends on SUSPEND (PPC_85xx || PPC_86xx) + depends on SUSPEND (PPC_85xx || PPC_86xx) !PPC_E500MC help Freescale MPC85xx/MPC86xx power management controller support (suspend/resume). For MPC83xx see platforms/83xx/suspend.c diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index b843e35..6c5f1c2 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -58,6 +58,8 @@ extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); #endif +extern void flush_dcache_L1(void); + #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ memcpy(dst, src, len); \ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index bb282dd..21e025b 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_FA_DUMP) += fadump.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o endif +obj-y += cache_fsl.o obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o diff --git a/arch/powerpc/kernel/cache_fsl.S b/arch/powerpc/kernel/cache_fsl.S new file mode 100644 index 000..25cd22e --- /dev/null +++ b/arch/powerpc/kernel/cache_fsl.S @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2009-2012 Freescale Semiconductor, Inc. All rights reserved. + * Scott Wood scottw...@freescale.com + * Dave Liu dave...@freescale.com + * + * 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/reg.h +#include asm/cputable.h +#include asm/ppc_asm.h +#include asm/asm-offsets.h + +#define L2CTL_L2E 0x8000 +#define L2CTL_L2I 0x4000 + + .section .text + +#ifdef CONFIG_FSL_PMC + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(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, L2CTL_L2E | L2CTL_L2I + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, L2CTL_L2I@h + bne 1b + mbar + + blr + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(invalidate_enable_L2) + mbar + isync + lwz r4, 0(r3) + li r5, 3 + rlwimi r4, r5, 30, L2CTL_L2E | L2CTL_L2I + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, L2CTL_L2I@h + bne 1b + mbar + + blr +#endif diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch
[PATCH 3/4] cpu: export cpu hotplug disable/enable functions as global functions
The cpufreq driver of mpc85xx will disable/enable cpu hotplug temporarily. Therefore, the related functions should be exported. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- include/linux/cpu.h |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/include/linux/cpu.h b/include/linux/cpu.h index ce7a074..df8f73d 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -146,6 +146,8 @@ void notify_cpu_starting(unsigned int cpu); extern void cpu_maps_update_begin(void); extern void cpu_maps_update_done(void); +extern void cpu_hotplug_disable_before_freeze(void); +extern void cpu_hotplug_enable_after_thaw(void); #else /* CONFIG_SMP */ #define cpu_notifier(fn, pri) do { (void)(fn); } while (0) @@ -167,6 +169,8 @@ static inline void cpu_maps_update_done(void) { } +static inline void cpu_hotplug_disable_before_freeze(void) {} +static inline void cpu_hotplug_enable_after_thaw(void) {} #endif /* CONFIG_SMP */ extern struct bus_type cpu_subsys; -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 4/4] powerpc/85xx: add support to JOG feature using cpufreq interface
Some 85xx silicons like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a atomic counter to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum. Subsequent revisions of MPC8536 have corrected the erratum. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com CC: Scott Wood scottw...@freescale.com --- arch/powerpc/platforms/85xx/Makefile |1 + arch/powerpc/platforms/85xx/cpufreq-jog.c | 388 + arch/powerpc/platforms/Kconfig| 11 + arch/powerpc/sysdev/fsl_pmc.c |3 + arch/powerpc/sysdev/fsl_soc.h |2 + 5 files changed, 405 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/cpufreq-jog.c diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 8a030a1..6156849 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_SMP) += smp.o obj-y += common.o obj-$(CONFIG_FSL_PMC) += sleep.o +obj-$(CONFIG_MPC85xx_CPUFREQ) += cpufreq-jog.o obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o diff --git a/arch/powerpc/platforms/85xx/cpufreq-jog.c b/arch/powerpc/platforms/85xx/cpufreq-jog.c new file mode 100644 index 000..ccc0c33 --- /dev/null +++ b/arch/powerpc/platforms/85xx/cpufreq-jog.c @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2008-2012 Freescale Semiconductor, Inc. + * Author: Dave Liu dave...@freescale.com + * Modifier: Chenhui Zhao chenhui.z...@freescale.com + * + * The cpufreq driver is for Freescale 85xx processor, + * based on arch/powerpc/platforms/cell/cbe_cpufreq.c + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 + * Christian Krafft kra...@de.ibm.com + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h +#include linux/cpufreq.h +#include linux/of_platform.h +#include linux/suspend.h +#include linux/cpu.h + +#include asm/prom.h +#include asm/time.h +#include asm/reg.h +#include asm/io.h +#include asm/machdep.h +#include asm/smp.h + +#include sysdev/fsl_soc.h + +static DEFINE_MUTEX(mpc85xx_switch_mutex); +static void __iomem *guts; + +static u32 sysfreq; +static unsigned int max_pll[2]; +static atomic_t in_jog_process; +static struct cpufreq_frequency_table *mpc85xx_freqs; +static int (*set_pll)(unsigned int cpu, unsigned int pll); + +static struct cpufreq_frequency_table mpc8536_freqs_table[] = { + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +static struct cpufreq_frequency_table p1022_freqs_table[] = { + {2, 0}, + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +#define FREQ_500MHz5 +#define FREQ_800MHz8 + +#define CORE_RATIO_STRIDE 8 +#define CORE_RATIO_MASK0x3f +#define CORE_RATIO_SHIFT 16 + +#define PORPLLSR 0x0 /* Power-On Reset PLL ratio status register */ + +#define PMJCR 0x7c/* Power Management Jog Control Register */ +#define PMJCR_CORE0_SPD0x1000 +#define PMJCR_CORE_SPD 0x2000 + +#define POWMGTCSR 0x80 /* Power management control and status register */ +#define POWMGTCSR_JOG 0x0020 +#define POWMGTCSR_INT_MASK 0x0f00 + +static void spin_while_jogging(void *dummy) +{ + unsigned long flags
[PATCH 2/4] fsl_pmc: Add API to enable device as wakeup event source
Add APIs for setting wakeup source and lossless Ethernet in low power modes. These APIs can be used by wake-on-packet feature. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/sysdev/fsl_pmc.c | 77 - arch/powerpc/sysdev/fsl_soc.h | 12 ++ 2 files changed, 88 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 45718c5..b6c8c8f 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -38,6 +38,7 @@ struct pmc_regs { __be32 powmgtcsr; #define POWMGTCSR_SLP 0x0002 #define POWMGTCSR_DPSLP0x0010 +#define POWMGTCSR_LOSSLESS 0x0040 __be32 res3[2]; /* 0xe008c: Power management clock disable register */ __be32 pmcdr; @@ -48,6 +49,77 @@ static unsigned int pmc_flag; #define PMC_SLEEP 0x1 #define PMC_DEEP_SLEEP 0x2 +#define PMC_LOSSLESS 0x4 + +#define PMCDR_MASK_INIT0x00e008e0 + +/** + * mpc85xx_pmc_set_wake - enable devices as wakeup event source + * @dev: a device affected + * @enable: True to enable event generation; false to disable + * + * This enables the device as a wakeup event source, or disables it. + * + * RETURN VALUE: + * 0 is returned on success. + * -EINVAL is returned if device is not supposed to wake up the system. + * -ENODEV is returned if PMC is unavailable. + * Error code depending on the platform is returned if both the platform and + * the native mechanism fail to enable the generation of wake-up events + */ +int mpc85xx_pmc_set_wake(struct device *dev, bool enable) +{ + int ret = 0; + struct device_node *clk_np; + const u32 *prop; + u32 pmcdr_mask; + + if (!pmc_regs) { + pr_err(%s: PMC is unavailable\n, __func__); + return -ENODEV; + } + + if (enable !device_may_wakeup(dev)) + return -EINVAL; + + clk_np = of_parse_phandle(dev-of_node, fsl,pmc-handle, 0); + if (!clk_np) + return -EINVAL; + + prop = of_get_property(clk_np, fsl,pmcdr-mask, NULL); + if (!prop) { + ret = -EINVAL; + goto out; + } + pmcdr_mask = be32_to_cpup(prop); + + if (enable) + /* clear to enable clock in low power mode */ + clrbits32(pmc_regs-pmcdr, pmcdr_mask); + else + setbits32(pmc_regs-pmcdr, pmcdr_mask); + +out: + of_node_put(clk_np); + return ret; +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_wake); + +/** + * mpc85xx_pmc_set_lossless_ethernet - enable lossless ethernet + * in (deep) sleep mode + * @enable: True to enable event generation; false to disable + */ +void mpc85xx_pmc_set_lossless_ethernet(int enable) +{ + if (pmc_flag PMC_LOSSLESS) { + if (enable) + setbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + else + clrbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + } +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_lossless_ethernet); static int pmc_suspend_enter(suspend_state_t state) { @@ -123,7 +195,10 @@ static int pmc_probe(struct platform_device *pdev) pmc_flag |= PMC_DEEP_SLEEP; if (of_device_is_compatible(np, fsl,p1022-pmc)) - pmc_flag |= PMC_DEEP_SLEEP; + pmc_flag |= PMC_DEEP_SLEEP | PMC_LOSSLESS; + + /* Init the Power Management Clock Disable Register. */ + setbits32(pmc_regs-pmcdr, PMCDR_MASK_INIT); suspend_set_ops(pmc_suspend_ops); diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 11d9f94..b1510ef 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -3,6 +3,7 @@ #ifdef __KERNEL__ #include asm/mmu.h +#include linux/platform_device.h struct spi_device; @@ -21,6 +22,17 @@ struct device_node; extern void fsl_rstcr_restart(char *cmd); +#ifdef CONFIG_FSL_PMC +extern int mpc85xx_pmc_set_wake(struct device *dev, bool enable); +extern void mpc85xx_pmc_set_lossless_ethernet(int enable); +#else +static inline int mpc85xx_pmc_set_wake(struct device *dev, bool enable) +{ + return -ENODEV; +} +#define mpc85xx_pmc_set_lossless_ethernet(enable) do { } while (0) +#endif + #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) /* The different ports that the DIU can be connected to */ -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] mpc85xx_defconfig: add VIA PATA support for MPC85xxCDS
Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- Replace this patch mpc85xx_defconfig: add IDE support for MPC85xxCDS. arch/powerpc/configs/mpc85xx_defconfig |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index ae9d852..627c257 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -116,6 +116,7 @@ CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_FSL=y CONFIG_PATA_ALI=y +CONFIG_PATA_VIA=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_FS_ENET=y -- 1.6.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 3/4] cpu: export cpu hotplug disable/enable functions as global functions
On Wed, Aug 08, 2012 at 11:43:22AM +0530, Srivatsa S. Bhat wrote: On 08/07/2012 11:21 PM, Kumar Gala wrote: On Aug 7, 2012, at 3:43 AM, Zhao Chenhui wrote: The cpufreq driver of mpc85xx will disable/enable cpu hotplug temporarily. Therefore, the related functions should be exported. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- include/linux/cpu.h |4 1 files changed, 4 insertions(+), 0 deletions(-) Rafael, Srivatsa, Wanted to get your ack on export these functions for direct calling by arch code. Why not just use get_online_cpus()/put_online_cpus()? In the case of suspend/resume/hibernation, we had introduced these CPU hotplug disable functions because we would end up doing CPU hotplug ourselves, further down the path. So if we did a get_online_cpus(), we would end up deadlocking ourselves. Whereas, the patch 4/4 looks like a straightforward case of wanting to simply disable CPU hotplug.. I don't see where you are doing CPU hotplug yourself in the path. So IMO, just get/put_online_cpus() should do. Regards, Srivatsa S. Bhat Thanks for your comment. I will try to use get/put_online_cpus() in my patch. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 3/4] cpu: export cpu hotplug disable/enable functions as global functions
On Tue, Aug 07, 2012 at 04:43:25PM +0800, Zhao Chenhui wrote: The cpufreq driver of mpc85xx will disable/enable cpu hotplug temporarily. Therefore, the related functions should be exported. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- include/linux/cpu.h |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/include/linux/cpu.h b/include/linux/cpu.h index ce7a074..df8f73d 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -146,6 +146,8 @@ void notify_cpu_starting(unsigned int cpu); extern void cpu_maps_update_begin(void); extern void cpu_maps_update_done(void); +extern void cpu_hotplug_disable_before_freeze(void); +extern void cpu_hotplug_enable_after_thaw(void); #else/* CONFIG_SMP */ #define cpu_notifier(fn, pri)do { (void)(fn); } while (0) @@ -167,6 +169,8 @@ static inline void cpu_maps_update_done(void) { } +static inline void cpu_hotplug_disable_before_freeze(void) {} +static inline void cpu_hotplug_enable_after_thaw(void) {} #endif /* CONFIG_SMP */ extern struct bus_type cpu_subsys; -- 1.6.4.1 Hi kumar, I will not use these API in the 4/4 patch. please ignore this patch. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 4/4] powerpc/85xx: add support to JOG feature using cpufreq interface
Some 85xx silicons like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a atomic counter to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum. Subsequent revisions of MPC8536 have corrected the erratum. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com CC: Scott Wood scottw...@freescale.com --- v2: * use get/put_online_cpus() to disable/enable cpu hotplug. arch/powerpc/platforms/85xx/Makefile |1 + arch/powerpc/platforms/85xx/cpufreq-jog.c | 388 + arch/powerpc/platforms/Kconfig| 11 + arch/powerpc/sysdev/fsl_pmc.c |3 + arch/powerpc/sysdev/fsl_soc.h |2 + 5 files changed, 405 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/cpufreq-jog.c diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 8a030a1..6156849 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_SMP) += smp.o obj-y += common.o obj-$(CONFIG_FSL_PMC) += sleep.o +obj-$(CONFIG_MPC85xx_CPUFREQ) += cpufreq-jog.o obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o diff --git a/arch/powerpc/platforms/85xx/cpufreq-jog.c b/arch/powerpc/platforms/85xx/cpufreq-jog.c new file mode 100644 index 000..287987b --- /dev/null +++ b/arch/powerpc/platforms/85xx/cpufreq-jog.c @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2008-2012 Freescale Semiconductor, Inc. + * Author: Dave Liu dave...@freescale.com + * Modifier: Chenhui Zhao chenhui.z...@freescale.com + * + * The cpufreq driver is for Freescale 85xx processor, + * based on arch/powerpc/platforms/cell/cbe_cpufreq.c + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 + * Christian Krafft kra...@de.ibm.com + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h +#include linux/cpufreq.h +#include linux/of_platform.h +#include linux/suspend.h +#include linux/cpu.h + +#include asm/prom.h +#include asm/time.h +#include asm/reg.h +#include asm/io.h +#include asm/machdep.h +#include asm/smp.h + +#include sysdev/fsl_soc.h + +static DEFINE_MUTEX(mpc85xx_switch_mutex); +static void __iomem *guts; + +static u32 sysfreq; +static unsigned int max_pll[2]; +static atomic_t in_jog_process; +static struct cpufreq_frequency_table *mpc85xx_freqs; +static int (*set_pll)(unsigned int cpu, unsigned int pll); + +static struct cpufreq_frequency_table mpc8536_freqs_table[] = { + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +static struct cpufreq_frequency_table p1022_freqs_table[] = { + {2, 0}, + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +#define FREQ_500MHz5 +#define FREQ_800MHz8 + +#define CORE_RATIO_STRIDE 8 +#define CORE_RATIO_MASK0x3f +#define CORE_RATIO_SHIFT 16 + +#define PORPLLSR 0x0 /* Power-On Reset PLL ratio status register */ + +#define PMJCR 0x7c/* Power Management Jog Control Register */ +#define PMJCR_CORE0_SPD0x1000 +#define PMJCR_CORE_SPD 0x2000 + +#define POWMGTCSR 0x80 /* Power management control and status register */ +#define POWMGTCSR_JOG 0x0020 +#define POWMGTCSR_INT_MASK 0x0f00 + +static void
Re: [PATCH 2/4] fsl_pmc: Add API to enable device as wakeup event source
On Sat, Aug 11, 2012 at 08:19:43AM -0500, Tabi Timur-B04825 wrote: On Tue, Aug 7, 2012 at 3:43 AM, Zhao Chenhui chenhui.z...@freescale.com wrote: + return -EINVAL; + + prop = of_get_property(clk_np, fsl,pmcdr-mask, NULL); + if (!prop) { + ret = -EINVAL; + goto out; + } + pmcdr_mask = be32_to_cpup(prop); + + if (enable) + /* clear to enable clock in low power mode */ + clrbits32(pmc_regs-pmcdr, pmcdr_mask); + else + setbits32(pmc_regs-pmcdr, pmcdr_mask); + +out: + of_node_put(clk_np); + return ret; +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_wake); Use EXPORT_SYMBOL, not EXPORT_SYMBOL_GPL. Hi kumar, Is that ok with upstream? -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/4] fsl_pmc: Add API to enable device as wakeup event source
On Sat, Aug 11, 2012 at 08:19:43AM -0500, Tabi Timur-B04825 wrote: On Tue, Aug 7, 2012 at 3:43 AM, Zhao Chenhui chenhui.z...@freescale.com wrote: +int mpc85xx_pmc_set_wake(struct device *dev, bool enable) +{ + int ret = 0; + struct device_node *clk_np; + const u32 *prop; + u32 pmcdr_mask; + + if (!pmc_regs) { + pr_err(%s: PMC is unavailable\n, __func__); You have a 'struct device', so please use dev_err instead. + return -ENODEV; + } + + if (enable !device_may_wakeup(dev)) + return -EINVAL; + + clk_np = of_parse_phandle(dev-of_node, fsl,pmc-handle, 0); + if (!clk_np) + return -EINVAL; + + prop = of_get_property(clk_np, fsl,pmcdr-mask, NULL); + if (!prop) { + ret = -EINVAL; + goto out; + } + pmcdr_mask = be32_to_cpup(prop); + + if (enable) + /* clear to enable clock in low power mode */ + clrbits32(pmc_regs-pmcdr, pmcdr_mask); + else + setbits32(pmc_regs-pmcdr, pmcdr_mask); + +out: + of_node_put(clk_np); + return ret; +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_wake); Use EXPORT_SYMBOL, not EXPORT_SYMBOL_GPL. + +/** + * mpc85xx_pmc_set_lossless_ethernet - enable lossless ethernet + * in (deep) sleep mode + * @enable: True to enable event generation; false to disable + */ +void mpc85xx_pmc_set_lossless_ethernet(int enable) Should this be 'bool enable'? @@ -21,6 +22,17 @@ struct device_node; extern void fsl_rstcr_restart(char *cmd); +#ifdef CONFIG_FSL_PMC +extern int mpc85xx_pmc_set_wake(struct device *dev, bool enable); +extern void mpc85xx_pmc_set_lossless_ethernet(int enable); Don't use 'extern' for functions. Why? I think there is no difference. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 02/17] powerpc/85xx: do not sync time base at boot time
From: Chen-Hui Zhao chenhui.z...@freescale.com The bootloader have done time base sync for all cores, so skip the synchronization process at boot time of kernel. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/platforms/85xx/smp.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 6a17599..35dae8e 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -62,6 +62,10 @@ static void mpc85xx_give_timebase(void) { unsigned long flags; + /* only do time base sync when system is running */ + if (system_state == SYSTEM_BOOTING) + return; + local_irq_save(flags); while (!tb_req) @@ -85,6 +89,10 @@ static void mpc85xx_take_timebase(void) { unsigned long flags; + /* only do time base sync when system is running */ + if (system_state == SYSTEM_BOOTING) + return; + local_irq_save(flags); tb_req = 1; -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 01/17] powerpc/85xx: fix a bug with the parameter of mpic_reset_core()
From: Chen-Hui Zhao chenhui.z...@freescale.com mpic_reset_core() need a logical cpu number instead of physical. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/platforms/85xx/smp.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 148c2f2..6a17599 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -201,7 +201,7 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) * We don't set the BPTR register here since it already points * to the boot page properly. */ - mpic_reset_core(hw_cpu); + mpic_reset_core(nr); /* * wait until core is ready... -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 04/17] powerpc/85xx: add sleep and deep sleep support
Some Freescale SoCs like MPC8536 and P1022 has the deep sleep mode in addtion to the sleep mode. 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. 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: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/platforms/85xx/Makefile |1 + arch/powerpc/platforms/85xx/sleep.S | 609 ++ arch/powerpc/sysdev/fsl_pmc.c| 91 - arch/powerpc/sysdev/fsl_soc.h|5 + 4 files changed, 688 insertions(+), 18 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 712e233..2f4713f 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -2,6 +2,7 @@ # Makefile for the PowerPC 85xx linux kernel. # obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_FSL_PMC) += sleep.o obj-y += common.o diff --git a/arch/powerpc/platforms/85xx/sleep.S b/arch/powerpc/platforms/85xx/sleep.S new file mode 100644 index 000..33d1d1f --- /dev/null +++ b/arch/powerpc/platforms/85xx/sleep.S @@ -0,0 +1,609 @@ +/* + * Enter and leave deep sleep state on MPC85xx + * + * Author: Scott Wood scottw...@freescale.com + * + * Copyright (C) 2006-2013 Freescale Semiconductor, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#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 + .align 12 + + /* +* r3 = high word of physical address of CCSR +* r4 = low word of physical address of CCSR +* r5 = JOG or deep sleep request +* JOG-0x0020, deep sleep-0x0010 +*/ +_GLOBAL(mpc85xx_enter_deep_sleep) + lis r6, ccsrbase_low@ha + stw r4, ccsrbase_low@l(r6) + lis r6, ccsrbase_high@ha + stw r3, ccsrbase_high@l(r6) + + lis r6, powmgtreq@ha + stw r5, powmgtreq@l(r6) + + lis r10, mpc85xx_sleep_save_area@h + ori r10, r10, mpc85xx_sleep_save_area@l + + mfspr r5, SPRN_HID0 + mfspr r6, SPRN_HID1 + + stw r5, SS_HID+0(r10) + stw r6, SS_HID+4(r10) + + mfspr r4, SPRN_IAC1 + mfspr r5, SPRN_IAC2 + mfspr r6, SPRN_DAC1 + mfspr r7, SPRN_DAC2 + + stw r4, SS_IAC+0(r10) + stw r5, SS_IAC+4(r10) + stw r6, SS_DAC+0(r10) + stw r7, SS_DAC+4(r10) + + mfspr r4, SPRN_DBCR0 + mfspr r5, SPRN_DBCR1 + mfspr r6, SPRN_DBCR2 + + stw r4, SS_DBCR+0(r10) + stw r5, SS_DBCR+4(r10) + stw r6, SS_DBCR+8(r10) + + mfspr r4, SPRN_PID0 + mfspr r5, SPRN_PID1 + mfspr r6, SPRN_PID2 + + stw r4, SS_PID+0(r10) + stw r5, SS_PID+4(r10) + stw r6, SS_PID+8(r10) + + mfspr r4, SPRN_SPRG0 + mfspr r5, SPRN_SPRG1 + mfspr r6, SPRN_SPRG2 + mfspr r7, SPRN_SPRG3 + + stw r4, SS_SPRG+0x00(r10) + stw r5, SS_SPRG+0x04(r10) + stw r6, SS_SPRG+0x08(r10) + stw r7, SS_SPRG+0x0c(r10) + + mfspr r4, SPRN_SPRG4 + mfspr r5, SPRN_SPRG5
[PATCH 05/17] fsl_pmc: Add API to enable device as wakeup event source
From: chenhui zhao chenhui.z...@freescale.com Add APIs for setting wakeup source and lossless Ethernet in low power modes. These APIs can be used by wake-on-packet feature. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/sysdev/fsl_pmc.c | 71 - arch/powerpc/sysdev/fsl_soc.h |9 + 2 files changed, 79 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index feede7d..ac0250c 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -34,6 +34,7 @@ struct pmc_regs { __be32 powmgtcsr; #define POWMGTCSR_SLP 0x0002 #define POWMGTCSR_DPSLP0x0010 +#define POWMGTCSR_LOSSLESS 0x0040 __be32 res3[2]; __be32 pmcdr; }; @@ -43,6 +44,74 @@ static unsigned int pmc_flag; #define PMC_SLEEP 0x1 #define PMC_DEEP_SLEEP 0x2 +#define PMC_LOSSLESS 0x4 + +/** + * mpc85xx_pmc_set_wake - enable devices as wakeup event source + * @pdev: platform device affected + * @enable: True to enable event generation; false to disable + * + * This enables the device as a wakeup event source, or disables it. + * + * RETURN VALUE: + * 0 is returned on success + * -EINVAL is returned if device is not supposed to wake up the system + * Error code depending on the platform is returned if both the platform and + * the native mechanism fail to enable the generation of wake-up events + */ +int mpc85xx_pmc_set_wake(struct platform_device *pdev, bool enable) +{ + int ret = 0; + struct device_node *clk_np; + u32 *prop; + u32 pmcdr_mask; + + if (!pmc_regs) { + pr_err(%s: PMC is unavailable\n, __func__); + return -ENODEV; + } + + if (enable !device_may_wakeup(pdev-dev)) + return -EINVAL; + + clk_np = of_parse_phandle(pdev-dev.of_node, fsl,pmc-handle, 0); + if (!clk_np) + return -EINVAL; + + prop = (u32 *)of_get_property(clk_np, fsl,pmcdr-mask, NULL); + if (!prop) { + ret = -EINVAL; + goto out; + } + pmcdr_mask = be32_to_cpup(prop); + + if (enable) + /* clear to enable clock in low power mode */ + clrbits32(pmc_regs-pmcdr, pmcdr_mask); + else + setbits32(pmc_regs-pmcdr, pmcdr_mask); + +out: + of_node_put(clk_np); + return ret; +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_wake); + +/** + * mpc85xx_pmc_set_lossless_ethernet - enable lossless ethernet + * in (deep) sleep mode + * @enable: True to enable event generation; false to disable + */ +void mpc85xx_pmc_set_lossless_ethernet(int enable) +{ + if (pmc_flag PMC_LOSSLESS) { + if (enable) + setbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + else + clrbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + } +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_lossless_ethernet); static int pmc_suspend_enter(suspend_state_t state) { @@ -117,7 +186,7 @@ static int pmc_probe(struct platform_device *pdev) pmc_flag |= PMC_DEEP_SLEEP; if (of_device_is_compatible(np, fsl,p1022-pmc)) - pmc_flag |= PMC_DEEP_SLEEP; + pmc_flag |= PMC_DEEP_SLEEP | PMC_LOSSLESS; suspend_set_ops(pmc_suspend_ops); diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 949377d..29a87ee 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -3,6 +3,7 @@ #ifdef __KERNEL__ #include asm/mmu.h +#include linux/platform_device.h struct spi_device; @@ -21,6 +22,14 @@ struct device_node; extern void fsl_rstcr_restart(char *cmd); +#ifdef CONFIG_FSL_PMC +int mpc85xx_pmc_set_wake(struct platform_device *pdev, bool enable); +void mpc85xx_pmc_set_lossless_ethernet(int enable); +#else +#define mpc85xx_pmc_set_wake(pdev, enable) +#define mpc85xx_pmc_set_lossless_ethernet(enable) +#endif + #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) /* The different ports that the DIU can be connected to */ -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 06/17] pm: add power node to dts
The Power Management device tree stub indicated that the platform supports Power Management feature. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi | 14 ++- arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/p1010si-post.dtsi |8 arch/powerpc/boot/dts/fsl/p1020si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1021si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1022si-post.dtsi | 11 -- arch/powerpc/boot/dts/fsl/p2020si-post.dtsi | 14 +++ arch/powerpc/boot/dts/fsl/pq3-power.dtsi | 48 + 10 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/pq3-power.dtsi diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi index c8b2daa..900f117 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi @@ -199,6 +199,10 @@ /include/ pq3-dma-0.dtsi /include/ pq3-etsec1-0.dtsi + enet0: ethernet@24000 { + fsl,wake-on-filer; + fsl,pmc-handle = etsec1_clk; + }; /include/ pq3-etsec1-timer-0.dtsi usb@22000 { @@ -222,9 +226,10 @@ }; /include/ pq3-etsec1-2.dtsi - - ethernet@26000 { + enet2: ethernet@26000 { cell-index = 1; + fsl,wake-on-filer; + fsl,pmc-handle = etsec3_clk; }; usb@2b000 { @@ -249,4 +254,9 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi + power@e0070 { + compatible = fsl,mpc8536-pmc, fsl,mpc8548-pmc; + }; }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi index b68eb11..ea7416a 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi @@ -188,4 +188,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi index 579d76c..dddb737 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi @@ -156,4 +156,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi index d44e25a..7313351 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi @@ -193,4 +193,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi index af12ead..01c8c33 100644 --- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -171,6 +171,8 @@ /include/ pq3-etsec2-0.dtsi enet0: ethernet@b { + fsl,pmc-handle = etsec1_clk; + queue-group@b { fsl,rx-bit-map = 0xff; fsl,tx-bit-map = 0xff; @@ -179,6 +181,8 @@ /include/ pq3-etsec2-1.dtsi enet1: ethernet@b1000 { + fsl,pmc-handle = etsec2_clk; + queue-group@b1000 { fsl,rx-bit-map = 0xff; fsl,tx-bit-map = 0xff; @@ -187,6 +191,8 @@ /include/ pq3-etsec2-2.dtsi enet2: ethernet@b2000 { + fsl,pmc-handle = etsec3_clk; + queue-group@b2000 { fsl,rx-bit-map = 0xff; fsl,tx-bit-map = 0xff; @@ -199,4 +205,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi index 68cc5e7..410e6e5 100644 --- a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi @@ -162,14 +162,17 @@ /include/ pq3-etsec2-0.dtsi enet0: enet0_grp2: ethernet@b { + fsl,pmc-handle = etsec1_clk; }; /include/ pq3-etsec2-1.dtsi enet1: enet1_grp2: ethernet@b1000 { + fsl,pmc-handle = etsec2_clk; }; /include/ pq3-etsec2-2.dtsi enet2: enet2_grp2: ethernet@b2000 { + fsl,pmc-handle = etsec3_clk; }; global-utilities@e { @@ -177,6 +180,8 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; /include/ pq3-etsec2-grp2-0.dtsi
[PATCH 07/17] fsl_pmc: update device bindings
From: Li Yang le...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- .../devicetree/bindings/powerpc/fsl/pmc.txt| 59 +++ 1 files changed, 34 insertions(+), 25 deletions(-) diff --git a/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt index 07256b7..f1f749f 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt @@ -9,15 +9,20 @@ Properties: fsl,mpc8548-pmc should be listed for any chip whose PMC is compatible. fsl,mpc8536-pmc should also be listed for any chip - whose PMC is compatible, and implies deep-sleep capability. + whose PMC is compatible, and implies deep-sleep capability and + wake on user defined packet(wakeup on ARP). + + fsl,p1022-pmc should be listed for any chip whose PMC is + compatible, and implies lossless Ethernet capability during sleep. fsl,mpc8641d-pmc should be listed for any chip whose PMC is compatible; all statements below that apply to fsl,mpc8548-pmc also apply to fsl,mpc8641d-pmc. Compatibility does not include bit assignments in SCCR/PMCDR/DEVDISR; these - bit assignments are indicated via the sleep specifier in each device's - sleep property. + bit assignments are indicated via the clock nodes. Device which has a + controllable clock source should have a fsl,pmc-handle property pointing + to the clock node. - reg: For devices compatible with fsl,mpc8349-pmc, the first resource is the PMC block, and the second resource is the Clock Configuration @@ -33,31 +38,35 @@ Properties: this is a phandle to an fsl,gtm node on which timer 4 can be used as a wakeup source from deep sleep. -Sleep specifiers: +Clock nodes: +The clock nodes are to describe the masks in PM controller registers for each +soc clock. +- fsl,pmcdr-mask: For fsl,mpc8548-pmc-compatible devices, the mask will be + ORed into PMCDR before suspend if the device using this clock is the wake-up + source and need to be running during low power mode; clear the mask if + otherwise. - fsl,mpc8349-pmc: Sleep specifiers consist of one cell. For each bit - that is set in the cell, the corresponding bit in SCCR will be saved - and cleared on suspend, and restored on resume. This sleep controller - supports disabling and resuming devices at any time. +- fsl,sccr-mask: For fsl,mpc8349-pmc-compatible devices, the corresponding + bit specified by the mask in SCCR will be saved and cleared on suspend, and + restored on resume. - fsl,mpc8536-pmc: Sleep specifiers consist of three cells, the third of - which will be ORed into PMCDR upon suspend, and cleared from PMCDR - upon resume. The first two cells are as described for fsl,mpc8578-pmc. - This sleep controller only supports disabling devices during system - sleep, or permanently. - - fsl,mpc8548-pmc: Sleep specifiers consist of one or two cells, the - first of which will be ORed into DEVDISR (and the second into - DEVDISR2, if present -- this cell should be zero or absent if the - hardware does not have DEVDISR2) upon a request for permanent device - disabling. This sleep controller does not support configuring devices - to disable during system sleep (unless supported by another compatible - match), or dynamically. +- fsl,devdisr-mask: Contain one or two cells, depending on the availability of + DEVDISR2 register. For compatible devices, the mask will be ORed into DEVDISR + or DEVDISR2 when the clock should be permenently disabled. Example: - power@b00 { - compatible = fsl,mpc8313-pmc, fsl,mpc8349-pmc; - reg = 0xb00 0x100 0xa00 0x100; - interrupts = 80 8; + power@e0070 { + compatible = fsl,mpc8536-pmc, fsl,mpc8548-pmc; + reg = 0xe0070 0x20; + + etsec1_clk: soc-clk@24 { + fsl,pmcdr-mask = 0x0080; + }; + etsec2_clk: soc-clk@25 { + fsl,pmcdr-mask = 0x0040; + }; + etsec3_clk: soc-clk@26 { + fsl,pmcdr-mask = 0x0020; + }; }; -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 08/17] powerpc/85xx: add support to JOG feature using cpufreq interface
From: chenhui zhao chenhui.z...@freescale.com Some MPC85xx SoCs like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a flag to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum. Subsequent revisions of MPC8536 have corrected the erratum. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/platforms/85xx/Makefile |1 + arch/powerpc/sysdev/fsl_soc.h|5 + drivers/cpufreq/Kconfig.powerpc | 10 + drivers/cpufreq/Makefile |1 + drivers/cpufreq/cpufreq-jog.c| 416 ++ include/linux/cpu.h |4 + kernel/cpu.c | 60 +++--- 7 files changed, 467 insertions(+), 30 deletions(-) create mode 100644 drivers/cpufreq/cpufreq-jog.c diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 2f4713f..4946be7 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_FSL_PMC) += sleep.o +obj-$(CONFIG_MPC85xx_CPUFREQ) += sleep.o obj-y += common.o diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 29a87ee..b7d5ef7 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -62,5 +62,10 @@ void fsl_hv_halt(void); * code can be compatible with both 32-bit 36-bit. */ extern void mpc85xx_enter_deep_sleep(u64 ccsrbar, u32 powmgtreq); + +static inline void mpc85xx_enter_jog(u64 ccsrbar, u32 powmgtreq) +{ + mpc85xx_enter_deep_sleep(ccsrbar, powmgtreq); +} #endif #endif diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc index e76992f..c47a662 100644 --- a/drivers/cpufreq/Kconfig.powerpc +++ b/drivers/cpufreq/Kconfig.powerpc @@ -5,3 +5,13 @@ config CPU_FREQ_MAPLE help This adds support for frequency switching on Maple 970FX Evaluation Board and compatible boards (IBM JS2x blades). + +config MPC85xx_CPUFREQ + bool Support for Freescale MPC85xx CPU freq + depends on PPC_85xx PPC32 !PPC_E500MC + select CPU_FREQ_TABLE + help + This adds support for dynamic frequency switching on + Freescale MPC85xx by cpufreq interface. MPC8536 and P1022 + have a JOG feature, which provides a dynamic mechanism + to lower or raise the CPU core clock at runtime. diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 863fd18..628fa0e 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -61,3 +61,4 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o ## # PowerPC platform drivers obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o +obj-$(CONFIG_MPC85xx_CPUFREQ) += cpufreq-jog.o diff --git a/drivers/cpufreq/cpufreq-jog.c b/drivers/cpufreq/cpufreq-jog.c new file mode 100644 index 000..5656d48 --- /dev/null +++ b/drivers/cpufreq/cpufreq-jog.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2008-2012 Freescale Semiconductor, Inc. + * Author: Dave Liu dave...@freescale.com + * Modifier: Chenhui Zhao chenhui.z...@freescale.com + * + * The cpufreq driver is for Freescale 85xx processor, + * based on arch/powerpc/platforms/cell/cbe_cpufreq.c + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 + * Christian Krafft kra...@de.ibm.com + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h
[PATCH 09/17] powerpc/85xx: add time base sync for SoCs based on e500mc/e5500
From: Chen-Hui Zhao chenhui.z...@freescale.com In the case of SMP, during the time base sync period, all time bases of online cores must stop, then start simultaneously. There is a RCPM (Run Control/Power Management) module in CoreNet based SoCs. Define a struct ccsr_rcpm to describe the register map. This patch supports SoCs based on e500mc/e5500, such as P4080, P5020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/include/asm/fsl_guts.h | 38 +++ arch/powerpc/platforms/85xx/smp.c | 32 + 2 files changed, 70 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index 77ced0b..4eac1cf 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -106,6 +106,44 @@ struct ccsr_guts { /* Alternate function signal multiplex control */ #define MPC85xx_PMUXCR_QE(x) (0x8000 (x)) +struct ccsr_rcpm { + u8 res[4]; + __be32 cdozsr; /* 0x0004 - Core Doze Status Register */ + u8 res0008[4]; + __be32 cdozcr; /* 0x000c - Core Doze Control Register */ + u8 res0010[4]; + __be32 cnapsr; /* 0x0014 - Core Nap Status Register */ + u8 res0018[4]; + __be32 cnapcr; /* 0x001c - Core Nap Control Register */ + u8 res0020[4]; + __be32 cdozpsr;/* 0x0024 - Core Doze Previous Status Register */ + u8 res0028[4]; + __be32 cnappsr;/* 0x002c - Core Nap Previous Status Register */ + u8 res0030[4]; + __be32 cwaitsr;/* 0x0034 - Core Wait Status Register */ + u8 res0038[4]; + __be32 cwdtdsr;/* 0x003c - Core watchdog detect status register */ + __be32 powmgtcsr; /* 0x0040 - Power Mangement Control Status Register */ + u8 res0044[12]; + __be32 ippdexpcr; /* 0x0050 - IP Powerdown Exception Control Register */ + u8 res0054[16]; + __be32 cpmimr; /* 0x0064 - Core PM IRQ Mask Register */ + u8 res0068[4]; + __be32 cpmcimr;/* 0x006c - Core PM Critical IRQ Mask Register */ + u8 res0070[4]; + __be32 cpmmcmr;/* 0x0074 - Core PM Machine Check Mask Register */ + u8 res0078[4]; + __be32 cpmnmimr; /* 0x007c - Core PM NMI Mask Register */ + u8 res0080[4]; + __be32 ctbenr; /* 0x0084 - Core Time Base Enable Register */ + u8 res0088[4]; + __be32 ctbckselr; /* 0x008c - Core Time Base Clock Select Register */ + u8 res0090[4]; + __be32 ctbhltcr; /* 0x0094 - Core Time Base Halt Control Register */ + u8 res0098[4]; + __be32 cmcpmaskcr; /* 0x00a4 - Core machine check mask control register */ +}; + #ifdef CONFIG_PPC_86xx #define CCSR_GUTS_DMACR_DEV_SSI0 /* DMA controller/channel set to SSI */ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 35dae8e..3de85a4 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -44,7 +44,36 @@ static struct ccsr_guts __iomem *guts; static u64 timebase; static int tb_req; static int tb_valid; +static u32 cur_booting_core; +#ifdef CONFIG_PPC_E500MC +/* get a physical mask of online cores and booting core */ +static inline u32 get_phy_cpu_mask(void) +{ + u32 mask; + int cpu; + + mask = 1 cur_booting_core; + for_each_online_cpu(cpu) + mask |= 1 get_hard_smp_processor_id(cpu); + + return mask; +} + +static void mpc85xx_timebase_freeze(int freeze) +{ + struct ccsr_rcpm __iomem *rcpm = (typeof(rcpm))guts; + u32 mask = get_phy_cpu_mask(); + + if (freeze) + clrbits32(rcpm-ctbenr, mask); + else + setbits32(rcpm-ctbenr, mask); + + /* read back to push the previos write */ + in_be32(rcpm-ctbenr); +} +#else static void mpc85xx_timebase_freeze(int freeze) { uint32_t mask; @@ -57,6 +86,7 @@ static void mpc85xx_timebase_freeze(int freeze) in_be32(guts-devdisr); } +#endif static void mpc85xx_give_timebase(void) { @@ -252,6 +282,7 @@ out: __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); flush_spin_table(spin_table); #endif + cur_booting_core = hw_cpu; local_irq_restore(flags); @@ -386,6 +417,7 @@ static const struct of_device_id mpc85xx_smp_guts_ids[] = { { .compatible = fsl,p1022-guts, }, { .compatible = fsl,p1023-guts, }, { .compatible = fsl,p2020-guts, }, + { .compatible = fsl,qoriq-rcpm-1.0, }, {}, }; -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org
[PATCH 10/17] powerpc/85xx: add cpu hotplug support for e500mc/e5500
From: Chen-Hui Zhao chenhui.z...@freescale.com Add support to disable and re-enable individual cores at runtime. This supports e500mc/e5500 core based SoCs. To prevent the register access race, only read/write RCPM registers in platform_cpu_die() on the boot cpu instead of accessing by individual cpus. Platform implementations can override the platform_cpu_die(). Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/smp.h|1 + arch/powerpc/kernel/smp.c | 16 ++- arch/powerpc/platforms/85xx/smp.c | 56 ++-- 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0e11a09..b6851be 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -347,7 +347,7 @@ config SWIOTLB config HOTPLUG_CPU bool Support for enabling/disabling CPUs depends on SMP HOTPLUG (PPC_PSERIES || \ - PPC_PMAC || PPC_POWERNV || (PPC_85xx !PPC_E500MC)) + PPC_PMAC || PPC_POWERNV || PPC_85xx) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 195ce2a..95be584 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -60,6 +60,7 @@ extern void smp_generic_take_timebase(void); DECLARE_PER_CPU(unsigned int, cpu_pvr); #ifdef CONFIG_HOTPLUG_CPU +void platform_cpu_die(unsigned int cpu); extern void migrate_irqs(void); int generic_cpu_disable(void); void generic_cpu_die(unsigned int cpu); diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 76bd9da..386c7ea 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -381,14 +381,28 @@ int generic_cpu_disable(void) return 0; } +/** + * platform_cpu_die() - do platform related operations on the boot cpu + * after CPU_DEAD is assigned to the variable cpu_state of the dying cpu. + * Platform implementations can override this. + * + * @cpu: the cpu to die + */ +void __attribute__ ((weak)) platform_cpu_die(unsigned int cpu) +{ + return; +} + void generic_cpu_die(unsigned int cpu) { int i; for (i = 0; i 100; i++) { smp_rmb(); - if (per_cpu(cpu_state, cpu) == CPU_DEAD) + if (per_cpu(cpu_state, cpu) == CPU_DEAD) { + platform_cpu_die(cpu); return; + } msleep(100); } printk(KERN_ERR CPU%d didn't die...\n, cpu); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 3de85a4..04e9fb9 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -40,7 +40,7 @@ struct epapr_spin_table { u32 pir; }; -static struct ccsr_guts __iomem *guts; +static void __iomem *guts_regs; static u64 timebase; static int tb_req; static int tb_valid; @@ -62,7 +62,7 @@ static inline u32 get_phy_cpu_mask(void) static void mpc85xx_timebase_freeze(int freeze) { - struct ccsr_rcpm __iomem *rcpm = (typeof(rcpm))guts; + struct ccsr_rcpm __iomem *rcpm = guts_regs; u32 mask = get_phy_cpu_mask(); if (freeze) @@ -76,6 +76,7 @@ static void mpc85xx_timebase_freeze(int freeze) #else static void mpc85xx_timebase_freeze(int freeze) { + struct ccsr_guts __iomem *guts = guts_regs; uint32_t mask; mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; @@ -84,6 +85,7 @@ static void mpc85xx_timebase_freeze(int freeze) else clrbits32(guts-devdisr, mask); + /* read back to push the previous write */ in_be32(guts-devdisr); } #endif @@ -136,7 +138,45 @@ static void mpc85xx_take_timebase(void) local_irq_restore(flags); } +static void core_reset_erratum(int hw_cpu) +{ +#ifdef CONFIG_PPC_E500MC + struct ccsr_rcpm __iomem *rcpm = guts_regs; + + clrbits32(rcpm-cnapcr, 1 hw_cpu); +#endif +} + #ifdef CONFIG_HOTPLUG_CPU +#ifdef CONFIG_PPC_E500MC +static void __cpuinit smp_85xx_mach_cpu_die(void) +{ + unsigned int cpu = smp_processor_id(); + + local_irq_disable(); + idle_task_exit(); + mb(); + + mtspr(SPRN_TCR, 0); + + __flush_disable_L1(); + disable_backside_L2_cache(); + + generic_set_cpu_dead(cpu); + + while (1); +} + +void platform_cpu_die(unsigned int cpu) +{ + unsigned int hw_cpu = get_hard_smp_processor_id(cpu); + struct ccsr_rcpm __iomem *rcpm = guts_regs; + + /* Core Nap Operation */ + setbits32(rcpm-cnapcr, 1 hw_cpu); +} +#else +/* for e500v1 and e500v2 */ static void __cpuinit smp_85xx_mach_cpu_die(void) { unsigned int cpu = smp_processor_id
[PATCH 11/17] powerpc/rcpm: add sleep feature for SoCs using RCPM
The SoCs which have a RCPM (Run Control/Power Management) module support power management feature. This patch implements sleep feature. In sleep mode, the clocks of cores and unused IP blocks will be turned off. The IP blocks which are allowed to wake up the system are still running. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/Kconfig|4 +- arch/powerpc/include/asm/fsl_guts.h |1 + arch/powerpc/platforms/85xx/Kconfig |1 + arch/powerpc/sysdev/Kconfig |5 ++ arch/powerpc/sysdev/Makefile|1 + arch/powerpc/sysdev/fsl_rcpm.c | 101 +++ 6 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/sysdev/fsl_rcpm.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index b6851be..0ad6e30 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -220,7 +220,7 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ - (PPC_85xx !PPC_E500MC) || PPC_86xx || PPC_PSERIES \ + FSL_SOC_BOOKE || PPC_86xx || PPC_PSERIES \ || 44x || 40x config PPC_DCR_NATIVE @@ -694,7 +694,7 @@ config FSL_PCI config FSL_PMC bool default y - depends on SUSPEND (PPC_85xx || PPC_86xx) + depends on SUSPEND ((PPC_85xx !PPC_E500MC) || PPC_86xx) help Freescale MPC85xx/MPC86xx power management controller support (suspend/resume). For MPC83xx see platforms/83xx/suspend.c diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index 4eac1cf..b8a08d5 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -124,6 +124,7 @@ struct ccsr_rcpm { u8 res0038[4]; __be32 cwdtdsr;/* 0x003c - Core watchdog detect status register */ __be32 powmgtcsr; /* 0x0040 - Power Mangement Control Status Register */ +#define RCPM_POWMGTCSR_SLP 0x0002 u8 res0044[12]; __be32 ippdexpcr; /* 0x0050 - IP Powerdown Exception Control Register */ u8 res0054[16]; diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 31dc066..bb5e09a 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -8,6 +8,7 @@ menuconfig FSL_SOC_BOOKE select FSL_PCI if PCI select SERIAL_8250_EXTENDED if SERIAL_8250 select SERIAL_8250_SHARE_IRQ if SERIAL_8250 + select FSL_CORENET_RCPM if SUSPEND PPC_E500MC default y if FSL_SOC_BOOKE diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig index a84fecf..6c22d91 100644 --- a/arch/powerpc/sysdev/Kconfig +++ b/arch/powerpc/sysdev/Kconfig @@ -33,3 +33,8 @@ config SCOM_DEBUGFS config GE_FPGA bool default n + +config FSL_CORENET_RCPM + bool + help +This option enables support for RCPM (Run Control/Power Management). diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index b0a518e..f12b856 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) obj-$(CONFIG_FSL_PMC) += fsl_pmc.o +obj-$(CONFIG_FSL_CORENET_RCPM) += fsl_rcpm.o obj-$(CONFIG_FSL_LBC) += fsl_lbc.o obj-$(CONFIG_FSL_IFC) += fsl_ifc.o obj-$(CONFIG_FSL_GTM) += fsl_gtm.o diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c new file mode 100644 index 000..fd789da --- /dev/null +++ b/arch/powerpc/sysdev/fsl_rcpm.c @@ -0,0 +1,101 @@ +/* + * RCPM(Run Control/Power Management) support + * + * Copyright 2012-2013 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 linux/types.h +#include linux/errno.h +#include linux/suspend.h +#include linux/device.h +#include linux/delay.h +#include linux/of_platform.h + +#include asm/io.h +#include asm/cacheflush.h +#include asm/fsl_guts.h + +static struct ccsr_rcpm __iomem *rcpm_regs; + +static int rcpm_suspend_enter(suspend_state_t state) +{ + int ret = 0; + + switch (state) { + case PM_SUSPEND_STANDBY: + + flush_dcache_L1(); + flush_backside_L2_cache(); + + setbits32(rcpm_regs-powmgtcsr, RCPM_POWMGTCSR_SLP); + + /* At this point, the device is in sleep mode. */ + + /* Upon resume, wait for SLP bit
[PATCH 12/17] powerpc/85xx: fix 64-bit support for cpu hotplug
From: Chen-Hui Zhao chenhui.z...@freescale.com * The paca[cpu].cpu_start is used as a signal to indicate if the cpu should start. So it should be cleard in .cpu_die(). * The limit memory routine only needs to be ran once at boot time by the boot cpu. Prevent other cpus running it again. * Rearrange the code segment in smp_85xx_kick_cpu() to share codes between PPC64 and PPC32 as far as possible. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/Kconfig |2 +- arch/powerpc/kernel/smp.c |3 +++ arch/powerpc/mm/tlb_nohash.c |6 -- arch/powerpc/platforms/85xx/smp.c | 23 +++ 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0ad6e30..aa5794b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -347,7 +347,7 @@ config SWIOTLB config HOTPLUG_CPU bool Support for enabling/disabling CPUs depends on SMP HOTPLUG (PPC_PSERIES || \ - PPC_PMAC || PPC_POWERNV || PPC_85xx) + PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 386c7ea..c8aa739 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -401,6 +401,9 @@ void generic_cpu_die(unsigned int cpu) smp_rmb(); if (per_cpu(cpu_state, cpu) == CPU_DEAD) { platform_cpu_die(cpu); +#ifdef CONFIG_PPC64 + paca[cpu].cpu_start = 0; +#endif return; } msleep(100); diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index 6888cad..de7bf06 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c @@ -627,8 +627,10 @@ static void __early_init_mmu(int boot_cpu) num_cams = (mfspr(SPRN_TLB1CFG) TLBnCFG_N_ENTRY) / 4; linear_map_top = map_mem_in_cams(linear_map_top, num_cams); - /* limit memory so we dont have linear faults */ - memblock_enforce_memory_limit(linear_map_top); + if (boot_cpu) { + /* limit memory so we dont have linear faults */ + memblock_enforce_memory_limit(linear_map_top); + } patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e); patch_exception(0x1e0, exc_instruction_tlb_miss_bolted_book3e); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 04e9fb9..febca8f 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -259,10 +259,6 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) spin_table = phys_to_virt(*cpu_rel_addr); local_irq_save(flags); -#ifdef CONFIG_PPC32 -#ifdef CONFIG_HOTPLUG_CPU - /* Corresponding to generic_set_cpu_dead() */ - generic_set_cpu_up(nr); if (system_state == SYSTEM_RUNNING) { /* @@ -306,12 +302,19 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) /* clear the acknowledge status */ __secondary_hold_acknowledge = -1; } -#endif flush_spin_table(spin_table); out_be32(spin_table-pir, hw_cpu); +#ifdef CONFIG_PPC32 out_be32(spin_table-addr_l, __pa(__early_start)); +#else + out_be32(spin_table-addr_h, + __pa(*(u64 *)generic_secondary_smp_init) 32); + out_be32(spin_table-addr_l, + __pa(*(u64 *)generic_secondary_smp_init) 0x); +#endif flush_spin_table(spin_table); +#ifdef CONFIG_PPC32 /* Wait a bit for the CPU to ack. */ if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu, 1, 100)) { @@ -320,18 +323,14 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) ret = -ENOENT; goto out; } -out: #else smp_generic_kick_cpu(nr); - - flush_spin_table(spin_table); - out_be32(spin_table-pir, hw_cpu); - out_be64((u64 *)(spin_table-addr_h), - __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); - flush_spin_table(spin_table); #endif + /* Corresponding to generic_set_cpu_dead() */ + generic_set_cpu_up(nr); cur_booting_core = hw_cpu; +out: local_irq_restore(flags); if (ioremappable) -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 13/17] powerpc/rcpm: add struct ccsr_rcpm_v2
From: Chen-Hui Zhao chenhui.z...@freescale.com Add struct ccsr_rcpm_v2 to descibe the v2 RCPM register map on some SoCs, such as T4240, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/include/asm/fsl_guts.h | 66 +++ 1 files changed, 66 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index b8a08d5..193d1f1 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -145,6 +145,72 @@ struct ccsr_rcpm { __be32 cmcpmaskcr; /* 0x00a4 - Core machine check mask control register */ }; +struct ccsr_rcpm_v2 { + u8 res_00[12]; + u32 tph10sr0; /* Thread PH10 Status Register */ + u8 res_10[12]; + u32 tph10setr0; /* Thread PH10 Set Control Register */ + u8 res_20[12]; + u32 tph10clrr0; /* Thread PH10 Clear Control Register */ + u8 res_30[12]; + u32 tph10psr0; /* Thread PH10 Previous Status Register */ + u8 res_40[12]; + u32 twaitsr0; /* Thread Wait Status Register */ + u8 res_50[96]; + u32 pcph15sr; /* Physical Core PH15 Status Register */ + u32 pcph15setr; /* Physical Core PH15 Set Control Register */ + u32 pcph15clrr; /* Physical Core PH15 Clear Control Register */ + u32 pcph15psr; /* Physical Core PH15 Prev Status Register */ + u8 res_c0[16]; + u32 pcph20sr; /* Physical Core PH20 Status Register */ + u32 pcph20setr; /* Physical Core PH20 Set Control Register */ + u32 pcph20clrr; /* Physical Core PH20 Clear Control Register */ + u32 pcph20psr; /* Physical Core PH20 Prev Status Register */ + u32 pcpw20sr; /* Physical Core PW20 Status Register */ + u8 res_e0[12]; + u32 pcph30sr; /* Physical Core PH30 Status Register */ + u32 pcph30setr; /* Physical Core PH30 Set Control Register */ + u32 pcph30clrr; /* Physical Core PH30 Clear Control Register */ + u32 pcph30psr; /* Physical Core PH30 Prev Status Register */ + u8 res_100[32]; + u32 ippwrgatecr;/* IP Power Gating Control Register */ + u8 res_124[12]; + u32 powmgtcsr; /* Power Management Control Status Reg */ +#define RCPM_POWMGTCSR_LPM20_RQ0x0010 +#define RCPM_POWMGTCSR_LPM20_ST0x0200 +#define RCPM_POWMGTCSR_P_LPM20_ST 0x0100 + u8 res_134[12]; + u32 ippdexpcr[4]; /* IP Powerdown Exception Control Reg */ + u8 res_150[12]; + u32 tpmimr0;/* Thread PM Interrupt Mask Reg */ + u8 res_160[12]; + u32 tpmcimr0; /* Thread PM Crit Interrupt Mask Reg */ + u8 res_170[12]; + u32 tpmmcmr0; /* Thread PM Machine Check Interrupt Mask Reg */ + u8 res_180[12]; + u32 tpmnmimr0; /* Thread PM NMI Mask Reg */ + u8 res_190[12]; + u32 tmcpmaskcr0;/* Thread Machine Check Mask Control Reg */ + u32 pctbenr;/* Physical Core Time Base Enable Reg */ + u32 pctbclkselr;/* Physical Core Time Base Clock Select */ + u32 tbclkdivr; /* Time Base Clock Divider Register */ + u8 res_1ac[4]; + u32 ttbhltcr[4];/* Thread Time Base Halt Control Register */ + u32 clpcl10sr; /* Cluster PCL10 Status Register */ + u32 clpcl10setr;/* Cluster PCL30 Set Control Register */ + u32 clpcl10clrr;/* Cluster PCL30 Clear Control Register */ + u32 clpcl10psr; /* Cluster PCL30 Prev Status Register */ + u32 cddslpsetr; /* Core Domain Deep Sleep Set Register */ + u32 cddslpclrr; /* Core Domain Deep Sleep Clear Register */ + u32 cdpwroksetr;/* Core Domain Power OK Set Register */ + u32 cdpwrokclrr;/* Core Domain Power OK Clear Register */ + u32 cdpwrensr; /* Core Domain Power Enable Status Register */ + u32 cddslsr;/* Core Domain Deep Sleep Status Register */ + u8 res_1e8[8]; + u32 dslpcntcr[8]; /* Deep Sleep Counter Cfg Register */ + u8 res_300[3568]; +}; + #ifdef CONFIG_PPC_86xx #define CCSR_GUTS_DMACR_DEV_SSI0 /* DMA controller/channel set to SSI */ -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 15/17] powerpc/85xx: add support for e6500 L1 cache operation
From: Chen-Hui Zhao chenhui.z...@freescale.com The L1 Data Cache of e6500 contains no modified data, no flush is required. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/kernel/fsl_booke_cache.S | 11 ++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/fsl_booke_cache.S b/arch/powerpc/kernel/fsl_booke_cache.S index 232c47b..24a52bb 100644 --- a/arch/powerpc/kernel/fsl_booke_cache.S +++ b/arch/powerpc/kernel/fsl_booke_cache.S @@ -65,13 +65,22 @@ _GLOBAL(flush_dcache_L1) blr +#define PVR_E6500 0x8040 + /* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ _GLOBAL(__flush_disable_L1) +/* L1 Data Cache of e6500 contains no modified data, no flush is required */ + mfspr r3, SPRN_PVR + rlwinm r4, r3, 16, 0x + lis r5, 0 + ori r5, r5, PVR_E6500@l + cmpwr4, r5 + beq 2f mflrr10 bl flush_dcache_L1 /* Flush L1 d-cache */ mtlrr10 - msync +2: msync mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ li r5, 2 rlwimi r4, r5, 0, 3 -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 14/17] powerpc/85xx: add time base sync support for e6500
From: Chen-Hui Zhao chenhui.z...@freescale.com For e6500, two threads in one core share one time base. Just need to do time base sync on first thread of one core, and skip it on the other thread. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/platforms/85xx/smp.c | 52 +++- 1 files changed, 44 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index febca8f..4ec2de2 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -26,6 +26,7 @@ #include asm/cacheflush.h #include asm/dbell.h #include asm/fsl_guts.h +#include asm/cputhreads.h #include sysdev/fsl_soc.h #include sysdev/mpic.h @@ -45,6 +46,7 @@ static u64 timebase; static int tb_req; static int tb_valid; static u32 cur_booting_core; +static bool rcpmv2; #ifdef CONFIG_PPC_E500MC /* get a physical mask of online cores and booting core */ @@ -53,26 +55,40 @@ static inline u32 get_phy_cpu_mask(void) u32 mask; int cpu; - mask = 1 cur_booting_core; - for_each_online_cpu(cpu) - mask |= 1 get_hard_smp_processor_id(cpu); + if (smt_capable()) { + /* two threads in one core share one time base */ + mask = 1 cpu_core_index_of_thread(cur_booting_core); + for_each_online_cpu(cpu) + mask |= 1 cpu_core_index_of_thread( + get_hard_smp_processor_id(cpu)); + } else { + mask = 1 cur_booting_core; + for_each_online_cpu(cpu) + mask |= 1 get_hard_smp_processor_id(cpu); + } return mask; } static void mpc85xx_timebase_freeze(int freeze) { - struct ccsr_rcpm __iomem *rcpm = guts_regs; + u32 *addr; u32 mask = get_phy_cpu_mask(); + if (rcpmv2) + addr = ((struct ccsr_rcpm_v2 *)guts_regs)-pctbenr; + else + addr = ((struct ccsr_rcpm *)guts_regs)-ctbenr; + if (freeze) - clrbits32(rcpm-ctbenr, mask); + clrbits32(addr, mask); else - setbits32(rcpm-ctbenr, mask); + setbits32(addr, mask); - /* read back to push the previos write */ - in_be32(rcpm-ctbenr); + /* read back to push the previous write */ + in_be32(addr); } + #else static void mpc85xx_timebase_freeze(int freeze) { @@ -98,6 +114,16 @@ static void mpc85xx_give_timebase(void) if (system_state == SYSTEM_BOOTING) return; +#ifdef CONFIG_PPC_E500MC + /* +* If the booting thread is not the first thread of the core, +* skip time base sync. +*/ + if (smt_capable() + cur_booting_core != cpu_first_thread_sibling(cur_booting_core)) + return; +#endif + local_irq_save(flags); while (!tb_req) @@ -125,6 +151,12 @@ static void mpc85xx_take_timebase(void) if (system_state == SYSTEM_BOOTING) return; +#ifdef CONFIG_PPC_E500MC + if (smt_capable() + cur_booting_core != cpu_first_thread_sibling(cur_booting_core)) + return; +#endif + local_irq_save(flags); tb_req = 1; @@ -465,6 +497,7 @@ static const struct of_device_id mpc85xx_smp_guts_ids[] = { { .compatible = fsl,p1023-guts, }, { .compatible = fsl,p2020-guts, }, { .compatible = fsl,qoriq-rcpm-1.0, }, + { .compatible = fsl,qoriq-rcpm-2, }, {}, }; @@ -491,6 +524,9 @@ void __init mpc85xx_smp_init(void) np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); if (np) { + if (of_device_is_compatible(np, fsl,qoriq-rcpm-2)) + rcpmv2 = true; + guts_regs = of_iomap(np, 0); of_node_put(np); if (!guts_regs) { -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 16/17] powerpc/smp: add cpu hotplug support for e6500
From: Chen-Hui Zhao chenhui.z...@freescale.com * Only if two threads of one core are offline, the core can enter PH20 state. * Clear PH20 bits before core reset, or core will not restart. * Introduced a variable l2cache_type in the struce cpu_spec to indentify the type of L2 cache. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/include/asm/cputable.h | 10 arch/powerpc/kernel/cputable.c |5 arch/powerpc/platforms/85xx/smp.c | 40 +- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index f326444..3715def 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -33,6 +33,13 @@ enum powerpc_pmc_type { PPC_PMC_G4 = 3, }; +enum powerpc_l2cache_type { + PPC_L2_CACHE_DEFAULT = 0, + PPC_L2_CACHE_CORE= 1, /* L2 cache used exclusively by one core */ + PPC_L2_CACHE_CLUSTER = 2, /* L2 cache shared by a core cluster */ + PPC_L2_CACHE_SOC = 3, /* L2 cache shared by all cores */ +}; + struct pt_regs; extern int machine_check_generic(struct pt_regs *regs); @@ -58,6 +65,9 @@ struct cpu_spec { unsigned inticache_bsize; unsigned intdcache_bsize; + /* L2 cache type */ + enum powerpc_l2cache_type l2cache_type; + /* number of performance monitor counters */ unsigned intnum_pmcs; enum powerpc_pmc_type pmc_type; diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index cc39139..a7329c1 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -2004,6 +2004,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_e500v1, .machine_check = machine_check_e500, .platform = ppc8540, + .l2cache_type = PPC_L2_CACHE_SOC, }, { /* e500v2 */ .pvr_mask = 0x, @@ -2023,6 +2024,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_e500v2, .machine_check = machine_check_e500, .platform = ppc8548, + .l2cache_type = PPC_L2_CACHE_SOC, }, { /* e500mc */ .pvr_mask = 0x, @@ -2040,6 +2042,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_e500mc, .machine_check = machine_check_e500mc, .platform = ppce500mc, + .l2cache_type = PPC_L2_CACHE_CORE, }, #endif /* CONFIG_PPC32 */ { /* e5500 */ @@ -2061,6 +2064,7 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif .machine_check = machine_check_e500mc, .platform = ppce5500, + .l2cache_type = PPC_L2_CACHE_CORE, }, { /* e6500 */ .pvr_mask = 0x, @@ -2082,6 +2086,7 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif .machine_check = machine_check_e500mc, .platform = ppce6500, + .l2cache_type = PPC_L2_CACHE_CLUSTER, }, #ifdef CONFIG_PPC32 { /* default match */ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 4ec2de2..f5a3cc7 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -174,13 +174,31 @@ static void core_reset_erratum(int hw_cpu) { #ifdef CONFIG_PPC_E500MC struct ccsr_rcpm __iomem *rcpm = guts_regs; + struct ccsr_rcpm_v2 __iomem *rcpm_v2 = guts_regs; - clrbits32(rcpm-cnapcr, 1 hw_cpu); + if (rcpmv2) + setbits32(rcpm_v2-pcph20clrr, + 1 cpu_core_index_of_thread(hw_cpu)); + else + clrbits32(rcpm-cnapcr, 1 hw_cpu); #endif } #ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_PPC_E500MC +static inline bool is_core_down(unsigned int thread) +{ + cpumask_t thd_mask; + + if (!smt_capable()) + return true; + + cpumask_shift_left(thd_mask, threads_core_mask, + cpu_core_index_of_thread(thread) * threads_per_core); + + return !cpumask_intersects(thd_mask, cpu_online_mask); +} + static void __cpuinit smp_85xx_mach_cpu_die(void) { unsigned int cpu = smp_processor_id(); @@ -191,8 +209,11 @@ static void __cpuinit smp_85xx_mach_cpu_die(void) mtspr(SPRN_TCR, 0); - __flush_disable_L1(); - disable_backside_L2_cache
[PATCH 17/17] powerpc/rcpm: add sleep support for T4/B4 chips
From: Chen-Hui Zhao chenhui.z...@freescale.com RCPM unit controls the power managment of T4/B4 chips. Software can access RCPM registers to put specific thread/core in PH10/PH15/PH20/PH30 state or put the device in LPM10/LPM20/LPM40 mode. The RCPM unit supports several wake up sources through internal timers and internal and external interrupts. When the device enter sleep state, it will be put in LPM20 mode. The command is echo standby /sys/power/state. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/sysdev/fsl_rcpm.c | 54 +--- 1 files changed, 50 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c index fd789da..6bd344b 100644 --- a/arch/powerpc/sysdev/fsl_rcpm.c +++ b/arch/powerpc/sysdev/fsl_rcpm.c @@ -20,6 +20,7 @@ #include asm/fsl_guts.h static struct ccsr_rcpm __iomem *rcpm_regs; +static struct ccsr_rcpm_v2 __iomem *rcpm2_regs; static int rcpm_suspend_enter(suspend_state_t state) { @@ -53,6 +54,41 @@ static int rcpm_suspend_enter(suspend_state_t state) return ret; } +static int rcpm_v2_suspend_enter(suspend_state_t state) +{ + int ret = 0; + + switch (state) { + case PM_SUSPEND_STANDBY: + + /* clear previous LPM20 status */ + setbits32(rcpm2_regs-powmgtcsr, RCPM_POWMGTCSR_P_LPM20_ST); + /* enter LPM20 status */ + setbits32(rcpm2_regs-powmgtcsr, RCPM_POWMGTCSR_LPM20_RQ); + + /* At this point, the device is in LPM20 status. */ + + /* resume ... */ + ret = spin_event_timeout( + (in_be32(rcpm2_regs-powmgtcsr) RCPM_POWMGTCSR_LPM20_ST) + == 0, 1, 10); + if (!ret) { + pr_err(%s: timeout waiting for LPM20 bit to be cleared\n, + __func__); + ret = -EINVAL; + } + + break; + + default: + ret = -EINVAL; + + } + + return ret; + +} + static int rcpm_suspend_valid(suspend_state_t state) { if (state == PM_SUSPEND_STANDBY) @@ -63,16 +99,25 @@ static int rcpm_suspend_valid(suspend_state_t state) static const struct platform_suspend_ops rcpm_suspend_ops = { .valid = rcpm_suspend_valid, - .enter = rcpm_suspend_enter, }; static int rcpm_probe(struct platform_device *pdev) { struct device_node *np = pdev-dev.of_node; - rcpm_regs = of_iomap(np, 0); - if (!rcpm_regs) - return -ENOMEM; + if (of_device_is_compatible(np, fsl,qoriq-rcpm-2)) { + rcpm2_regs = of_iomap(np, 0); + if (!rcpm2_regs) + return -ENOMEM; + + rcpm_suspend_ops.enter = rcpm_v2_suspend_enter; + } else { + rcpm_regs = of_iomap(np, 0); + if (!rcpm_regs) + return -ENOMEM; + + rcpm_suspend_ops.enter = rcpm_suspend_enter; + } suspend_set_ops(rcpm_suspend_ops); @@ -82,6 +127,7 @@ static int rcpm_probe(struct platform_device *pdev) static const struct of_device_id rcpm_ids[] = { { .compatible = fsl,qoriq-rcpm-1.0, }, + { .compatible = fsl,qoriq-rcpm-2, }, { }, }; -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 08/17] powerpc/85xx: add support to JOG feature using cpufreq interface
On Sun, Apr 07, 2013 at 10:30:41AM +0800, Tang Yuantian-B29983 wrote: Also send this patch to cpuf...@vger.kernel.org and linux...@vger.kernel.org And better to rebase it on git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git Thanks, Yuantian OK. Thanks. -Chenhui -Original Message- From: Linuxppc-dev [mailto:linuxppc-dev- bounces+b29983=freescale@lists.ozlabs.org] On Behalf Of Zhao Chenhui Sent: 2013年4月3日 21:09 To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH 08/17] powerpc/85xx: add support to JOG feature using cpufreq interface From: chenhui zhao chenhui.z...@freescale.com Some MPC85xx SoCs like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a flag to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum. Subsequent revisions of MPC8536 have corrected the erratum. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 03/17] powerpc/85xx: cache operations for Freescale SoCs based on BOOK3E
On Wed, Apr 03, 2013 at 09:09:11PM +0800, Zhao Chenhui wrote: These cache operations support Freescale SoCs based on BOOK3E. Move L1 cache operations to fsl_booke_cache.S in order to maintain easily. And, add cache operations for backside L2 cache and platform cache. The backside L2 cache appears on e500mc and e5500 core. The platform cache supported by this patch is L2 Look-Aside Cache, which appears on SoCs with e500v1/e500v2 core, such as MPC8572, P1020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/include/asm/cacheflush.h |8 ++ arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/fsl_booke_cache.S | 210 + arch/powerpc/kernel/head_fsl_booke.S | 74 4 files changed, 219 insertions(+), 74 deletions(-) create mode 100644 arch/powerpc/kernel/fsl_booke_cache.S Are there any comments about the set of patches? -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 01/15] powerpc/85xx: cache operations for Freescale SoCs based on BOOK3E
These cache operations support Freescale SoCs based on BOOK3E. Move L1 cache operations to fsl_booke_cache.S in order to maintain easily. And, add cache operations for backside L2 cache and platform cache. The backside L2 cache appears on e500mc and e5500 core. The platform cache supported by this patch is L2 Look-Aside Cache, which appears on SoCs with e500v1/e500v2 core, such as MPC8572, P1020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/include/asm/cacheflush.h |8 ++ arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/fsl_booke_cache.S | 210 + arch/powerpc/kernel/head_fsl_booke.S | 74 4 files changed, 219 insertions(+), 74 deletions(-) create mode 100644 arch/powerpc/kernel/fsl_booke_cache.S diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index b843e35..bc3f937 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -32,6 +32,14 @@ extern void flush_dcache_page(struct page *page); extern void __flush_disable_L1(void); +#ifdef CONFIG_FSL_SOC_BOOKE +void flush_dcache_L1(void); +void flush_backside_L2_cache(void); +void disable_backside_L2_cache(void); +void flush_disable_L2(void); +void invalidate_enable_L2(void); +#endif + extern void __flush_icache_range(unsigned long, unsigned long); static inline void flush_icache_range(unsigned long start, unsigned long stop) { diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f960a79..4acf739 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -87,6 +87,7 @@ extra-$(CONFIG_8xx) := head_8xx.o extra-y+= vmlinux.lds obj-$(CONFIG_RELOCATABLE_PPC32)+= reloc_32.o +obj-$(CONFIG_FSL_SOC_BOOKE)+= fsl_booke_cache.o obj-$(CONFIG_PPC32)+= entry_32.o setup_32.o obj-$(CONFIG_PPC64)+= dma-iommu.o iommu.o diff --git a/arch/powerpc/kernel/fsl_booke_cache.S b/arch/powerpc/kernel/fsl_booke_cache.S new file mode 100644 index 000..232c47b --- /dev/null +++ b/arch/powerpc/kernel/fsl_booke_cache.S @@ -0,0 +1,210 @@ +/* + * Copyright 2009-2013 Freescale Semiconductor, Inc. + * Scott Wood scottw...@freescale.com + * Dave Liu dave...@freescale.com + * + * 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/reg.h +#include asm/page.h +#include asm/ppc_asm.h +#include asm/asm-offsets.h + + .section .text + +/L1 Cache/ + +/* flush L1 d-cache */ +_GLOBAL(flush_dcache_L1) + mfspr r3,SPRN_L1CFG0 + + rlwinm r5,r3,9,3 /* Extract cache block size */ + twlgti r5,1/* Only 32 and 64 byte cache blocks +* are currently defined. +*/ + li r4,32 + subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - +* log2(number of ways) +*/ + slw r5,r4,r5/* r5 = cache block size */ + + rlwinm r7,r3,0,0xff/* Extract number of KiB in the cache */ + mulli r7,r7,13/* An 8-way cache will require 13 +* loads per set. +*/ + slw r7,r7,r6 + + /* save off HID0 and set DCFA */ + mfspr r8,SPRN_HID0 + ori r9,r8,HID0_DCFA@l + mtspr SPRN_HID0,r9 + isync + + LOAD_REG_IMMEDIATE(r4, KERNELBASE) + mtctr r7 + +1: lwz r3,0(r4)/* Load... */ + add r4,r4,r5 + bdnz1b + + msync + LOAD_REG_IMMEDIATE(r4, KERNELBASE) + mtctr r7 + +1: dcbf0,r4/* ...and flush. */ + add r4,r4,r5 + bdnz1b + + /* restore HID0 */ + mtspr SPRN_HID0,r8 + isync + + blr + +/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ +_GLOBAL(__flush_disable_L1) + mflrr10 + bl flush_dcache_L1 /* Flush L1 d-cache */ + mtlrr10 + + msync + mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + msync + isync + mtspr SPRN_L1CSR0, r4 + isync + + msync +1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ + andi. r4, r4, 2 + bne 1b + + msync + mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + msync + isync + mtspr SPRN_L1CSR1, r4 + isync + msync + + blr
[PATCH v2 02/15] powerpc/85xx: add sleep and deep sleep support
Some Freescale SoCs like MPC8536 and P1022 has the deep sleep mode in addtion to the sleep mode. 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. 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: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/platforms/85xx/Makefile |1 + arch/powerpc/platforms/85xx/sleep.S | 621 ++ arch/powerpc/sysdev/fsl_pmc.c| 98 +- arch/powerpc/sysdev/fsl_soc.h|5 + 4 files changed, 707 insertions(+), 18 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 2eab37e..a35bab7 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -2,6 +2,7 @@ # Makefile for the PowerPC 85xx linux kernel. # obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_FSL_PMC) += sleep.o obj-y += common.o diff --git a/arch/powerpc/platforms/85xx/sleep.S b/arch/powerpc/platforms/85xx/sleep.S new file mode 100644 index 000..5a43adb --- /dev/null +++ b/arch/powerpc/platforms/85xx/sleep.S @@ -0,0 +1,621 @@ +/* + * Enter and leave deep sleep/sleep state on MPC85xx + * + * Author: Scott Wood scottw...@freescale.com + * + * Copyright (C) 2006-2013 Freescale Semiconductor, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include asm/page.h +#include asm/ppc_asm.h +#include asm/reg.h +#include asm/asm-offsets.h +#include asm/mmu.h + +#define CCSR_ADDR 0xf000 + +#define L2C_OFFSET 0x2 /* L2 Cache Controller offset */ + +#define BPTR_OFFSET0x20 /* Boot Page Translation Register */ +#define BPTR_EN0x8000 + +#define PMRCCR_OFFSET 0xe0084 +#define PMRCCR_VRCNT_PRE_MASK 0x1f00 +#define PMRCCR_VRCNT_MASK 0x00ff + +#define POWMGTSCR_OFFSET 0xe0080 +#define POWMGTSCR_DPSLP0x0010 /* deep sleep mode */ + +#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 + .align 12 + + /* +* r3 = high word of physical address of CCSR +* r4 = low word of physical address of CCSR +* r5 = JOG or deep sleep request +* JOG-0x0020, deep sleep-0x0010 +*/ +_GLOBAL(mpc85xx_enter_deep_sleep) + lis r6, ccsrbase_low@ha + stw r4, ccsrbase_low@l(r6) + lis r6, ccsrbase_high@ha + stw r3, ccsrbase_high@l(r6) + + lis r6, powmgtreq@ha + stw r5, powmgtreq@l(r6) + + lis r10, mpc85xx_sleep_save_area@h + ori r10, r10, mpc85xx_sleep_save_area@l + + mfspr r5, SPRN_HID0 + mfspr r6, SPRN_HID1 + + stw r5, SS_HID+0(r10) + stw r6, SS_HID+4(r10) + + mfspr r4, SPRN_IAC1 + mfspr r5, SPRN_IAC2 + mfspr r6, SPRN_DAC1 + mfspr r7, SPRN_DAC2 + + stw r4, SS_IAC+0(r10) + stw r5, SS_IAC+4(r10) + stw r6, SS_DAC+0(r10) + stw r7, SS_DAC+4(r10) + + mfspr r4, SPRN_DBCR0 + mfspr r5, SPRN_DBCR1 + mfspr r6, SPRN_DBCR2 + + stw r4, SS_DBCR+0(r10) + stw r5, SS_DBCR+4(r10) + stw r6, SS_DBCR+8(r10) + + mfspr r4, SPRN_PID0
[PATCH v2 03/15] fsl_pmc: Add API to enable device as wakeup event source
From: chenhui zhao chenhui.z...@freescale.com Add APIs for setting wakeup source and lossless Ethernet in low power modes. These APIs can be used by wake-on-packet feature. Change-Id: I1803dcd4571af1eac49b43d99c578e7f99e2c278 Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jin Qing b24...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/sysdev/fsl_pmc.c | 72 - arch/powerpc/sysdev/fsl_soc.h | 11 ++ 2 files changed, 82 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 6c2c8b3..94ae476 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -38,6 +38,7 @@ struct pmc_regs { __be32 powmgtcsr; #define POWMGTCSR_SLP 0x0002 #define POWMGTCSR_DPSLP0x0010 +#define POWMGTCSR_LOSSLESS 0x0040 __be32 res3[2]; /* 0xe008c: Power management clock disable register */ __be32 pmcdr; @@ -48,6 +49,75 @@ static unsigned int pmc_flag; #define PMC_SLEEP 0x1 #define PMC_DEEP_SLEEP 0x2 +#define PMC_LOSSLESS 0x4 + +/** + * mpc85xx_pmc_set_wake - enable devices as wakeup event source + * @dev: a device affected + * @enable: True to enable event generation; false to disable + * + * This enables the device as a wakeup event source, or disables it. + * + * RETURN VALUE: + * 0 is returned on success. + * -EINVAL is returned if device is not supposed to wake up the system. + * -ENODEV is returned if PMC is unavailable. + * Error code depending on the platform is returned if both the platform and + * the native mechanism fail to enable the generation of wake-up events + */ +int mpc85xx_pmc_set_wake(struct device *dev, bool enable) +{ + int ret = 0; + struct device_node *clk_np; + const u32 *prop; + u32 pmcdr_mask; + + if (!pmc_regs) { + dev_err(dev, %s: PMC is unavailable\n, __func__); + return -ENODEV; + } + + if (enable !device_may_wakeup(dev)) + return -EINVAL; + + clk_np = of_parse_phandle(dev-of_node, fsl,pmc-handle, 0); + if (!clk_np) + return -EINVAL; + + prop = of_get_property(clk_np, fsl,pmcdr-mask, NULL); + if (!prop) { + ret = -EINVAL; + goto out; + } + pmcdr_mask = be32_to_cpup(prop); + + if (enable) + /* clear to enable clock in low power mode */ + clrbits32(pmc_regs-pmcdr, pmcdr_mask); + else + setbits32(pmc_regs-pmcdr, pmcdr_mask); + +out: + of_node_put(clk_np); + return ret; +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_wake); + +/** + * mpc85xx_pmc_set_lossless_ethernet - enable lossless ethernet + * in (deep) sleep mode + * @enable: True to enable event generation; false to disable + */ +void mpc85xx_pmc_set_lossless_ethernet(int enable) +{ + if (pmc_flag PMC_LOSSLESS) { + if (enable) + setbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + else + clrbits32(pmc_regs-powmgtcsr, POWMGTCSR_LOSSLESS); + } +} +EXPORT_SYMBOL_GPL(mpc85xx_pmc_set_lossless_ethernet); static int pmc_suspend_enter(suspend_state_t state) { @@ -122,7 +192,7 @@ static int pmc_probe(struct platform_device *pdev) pmc_flag |= PMC_DEEP_SLEEP; if (of_device_is_compatible(np, fsl,p1022-pmc)) - pmc_flag |= PMC_DEEP_SLEEP; + pmc_flag |= PMC_DEEP_SLEEP | PMC_LOSSLESS; suspend_set_ops(pmc_suspend_ops); diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 949377d..e58f4dd 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -21,6 +21,17 @@ struct device_node; extern void fsl_rstcr_restart(char *cmd); +#ifdef CONFIG_FSL_PMC +int mpc85xx_pmc_set_wake(struct device *dev, bool enable); +void mpc85xx_pmc_set_lossless_ethernet(int enable); +#else +static inline int mpc85xx_pmc_set_wake(struct device *dev, bool enable) +{ + return -ENODEV; +} +#define mpc85xx_pmc_set_lossless_ethernet(enable) do { } while (0) +#endif + #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) /* The different ports that the DIU can be connected to */ -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 04/15] pm: add power node to dts
The Power Management device tree stub indicated that the platform supports Power Management feature. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi | 14 ++- arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/p1010si-post.dtsi |8 arch/powerpc/boot/dts/fsl/p1020si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1021si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1022si-post.dtsi | 11 -- arch/powerpc/boot/dts/fsl/p2020si-post.dtsi | 14 +++ arch/powerpc/boot/dts/fsl/pq3-power.dtsi | 48 + 10 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/pq3-power.dtsi diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi index c8b2daa..900f117 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi @@ -199,6 +199,10 @@ /include/ pq3-dma-0.dtsi /include/ pq3-etsec1-0.dtsi + enet0: ethernet@24000 { + fsl,wake-on-filer; + fsl,pmc-handle = etsec1_clk; + }; /include/ pq3-etsec1-timer-0.dtsi usb@22000 { @@ -222,9 +226,10 @@ }; /include/ pq3-etsec1-2.dtsi - - ethernet@26000 { + enet2: ethernet@26000 { cell-index = 1; + fsl,wake-on-filer; + fsl,pmc-handle = etsec3_clk; }; usb@2b000 { @@ -249,4 +254,9 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi + power@e0070 { + compatible = fsl,mpc8536-pmc, fsl,mpc8548-pmc; + }; }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi index b68eb11..ea7416a 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi @@ -188,4 +188,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi index 579d76c..dddb737 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi @@ -156,4 +156,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi index d44e25a..7313351 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi @@ -193,4 +193,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi index af12ead..01c8c33 100644 --- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -171,6 +171,8 @@ /include/ pq3-etsec2-0.dtsi enet0: ethernet@b { + fsl,pmc-handle = etsec1_clk; + queue-group@b { fsl,rx-bit-map = 0xff; fsl,tx-bit-map = 0xff; @@ -179,6 +181,8 @@ /include/ pq3-etsec2-1.dtsi enet1: ethernet@b1000 { + fsl,pmc-handle = etsec2_clk; + queue-group@b1000 { fsl,rx-bit-map = 0xff; fsl,tx-bit-map = 0xff; @@ -187,6 +191,8 @@ /include/ pq3-etsec2-2.dtsi enet2: ethernet@b2000 { + fsl,pmc-handle = etsec3_clk; + queue-group@b2000 { fsl,rx-bit-map = 0xff; fsl,tx-bit-map = 0xff; @@ -199,4 +205,6 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; diff --git a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi index 68cc5e7..410e6e5 100644 --- a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi @@ -162,14 +162,17 @@ /include/ pq3-etsec2-0.dtsi enet0: enet0_grp2: ethernet@b { + fsl,pmc-handle = etsec1_clk; }; /include/ pq3-etsec2-1.dtsi enet1: enet1_grp2: ethernet@b1000 { + fsl,pmc-handle = etsec2_clk; }; /include/ pq3-etsec2-2.dtsi enet2: enet2_grp2: ethernet@b2000 { + fsl,pmc-handle = etsec3_clk; }; global-utilities@e { @@ -177,6 +180,8 @@ reg = 0xe 0x1000; fsl,has-rstcr; }; + +/include/ pq3-power.dtsi }; /include/ pq3-etsec2-grp2-0.dtsi
[PATCH v2 05/15] fsl_pmc: update device bindings
From: Li Yang le...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- .../devicetree/bindings/powerpc/fsl/pmc.txt| 59 +++ 1 files changed, 34 insertions(+), 25 deletions(-) diff --git a/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt index 07256b7..f1f749f 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt @@ -9,15 +9,20 @@ Properties: fsl,mpc8548-pmc should be listed for any chip whose PMC is compatible. fsl,mpc8536-pmc should also be listed for any chip - whose PMC is compatible, and implies deep-sleep capability. + whose PMC is compatible, and implies deep-sleep capability and + wake on user defined packet(wakeup on ARP). + + fsl,p1022-pmc should be listed for any chip whose PMC is + compatible, and implies lossless Ethernet capability during sleep. fsl,mpc8641d-pmc should be listed for any chip whose PMC is compatible; all statements below that apply to fsl,mpc8548-pmc also apply to fsl,mpc8641d-pmc. Compatibility does not include bit assignments in SCCR/PMCDR/DEVDISR; these - bit assignments are indicated via the sleep specifier in each device's - sleep property. + bit assignments are indicated via the clock nodes. Device which has a + controllable clock source should have a fsl,pmc-handle property pointing + to the clock node. - reg: For devices compatible with fsl,mpc8349-pmc, the first resource is the PMC block, and the second resource is the Clock Configuration @@ -33,31 +38,35 @@ Properties: this is a phandle to an fsl,gtm node on which timer 4 can be used as a wakeup source from deep sleep. -Sleep specifiers: +Clock nodes: +The clock nodes are to describe the masks in PM controller registers for each +soc clock. +- fsl,pmcdr-mask: For fsl,mpc8548-pmc-compatible devices, the mask will be + ORed into PMCDR before suspend if the device using this clock is the wake-up + source and need to be running during low power mode; clear the mask if + otherwise. - fsl,mpc8349-pmc: Sleep specifiers consist of one cell. For each bit - that is set in the cell, the corresponding bit in SCCR will be saved - and cleared on suspend, and restored on resume. This sleep controller - supports disabling and resuming devices at any time. +- fsl,sccr-mask: For fsl,mpc8349-pmc-compatible devices, the corresponding + bit specified by the mask in SCCR will be saved and cleared on suspend, and + restored on resume. - fsl,mpc8536-pmc: Sleep specifiers consist of three cells, the third of - which will be ORed into PMCDR upon suspend, and cleared from PMCDR - upon resume. The first two cells are as described for fsl,mpc8578-pmc. - This sleep controller only supports disabling devices during system - sleep, or permanently. - - fsl,mpc8548-pmc: Sleep specifiers consist of one or two cells, the - first of which will be ORed into DEVDISR (and the second into - DEVDISR2, if present -- this cell should be zero or absent if the - hardware does not have DEVDISR2) upon a request for permanent device - disabling. This sleep controller does not support configuring devices - to disable during system sleep (unless supported by another compatible - match), or dynamically. +- fsl,devdisr-mask: Contain one or two cells, depending on the availability of + DEVDISR2 register. For compatible devices, the mask will be ORed into DEVDISR + or DEVDISR2 when the clock should be permenently disabled. Example: - power@b00 { - compatible = fsl,mpc8313-pmc, fsl,mpc8349-pmc; - reg = 0xb00 0x100 0xa00 0x100; - interrupts = 80 8; + power@e0070 { + compatible = fsl,mpc8536-pmc, fsl,mpc8548-pmc; + reg = 0xe0070 0x20; + + etsec1_clk: soc-clk@24 { + fsl,pmcdr-mask = 0x0080; + }; + etsec2_clk: soc-clk@25 { + fsl,pmcdr-mask = 0x0040; + }; + etsec3_clk: soc-clk@26 { + fsl,pmcdr-mask = 0x0020; + }; }; -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 06/15] powerpc/85xx: add support to JOG feature using cpufreq interface
From: chenhui zhao chenhui.z...@freescale.com Some 85xx silicons like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a atomic counter to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum. Subsequent revisions of MPC8536 have corrected the erratum. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com CC: Scott Wood scottw...@freescale.com --- arch/powerpc/platforms/85xx/Makefile |1 + drivers/cpufreq/Kconfig.powerpc | 10 + drivers/cpufreq/Makefile |1 + drivers/cpufreq/mpc85xx-cpufreq.c| 390 ++ 4 files changed, 402 insertions(+), 0 deletions(-) create mode 100644 drivers/cpufreq/mpc85xx-cpufreq.c diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index a35bab7..da53bde 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_FSL_PMC) += sleep.o +obj-$(CONFIG_CPU_FREQ_MPC85xx) += sleep.o obj-y += common.o diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc index e76992f..ba06a00 100644 --- a/drivers/cpufreq/Kconfig.powerpc +++ b/drivers/cpufreq/Kconfig.powerpc @@ -5,3 +5,13 @@ config CPU_FREQ_MAPLE help This adds support for frequency switching on Maple 970FX Evaluation Board and compatible boards (IBM JS2x blades). + +config CPU_FREQ_MPC85xx + bool Support for Freescale MPC85xx CPU freq + depends on PPC_85xx PPC32 !PPC_E500MC + select CPU_FREQ_TABLE + help + This adds support for dynamic frequency switching on + Freescale MPC85xx by cpufreq interface. MPC8536 and P1022 + have a JOG feature, which provides a dynamic mechanism + to lower or raise the CPU core clock at runtime. diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 863fd18..e7aecc5 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -61,3 +61,4 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o ## # PowerPC platform drivers obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o +obj-$(CONFIG_CPU_FREQ_MPC85xx) += mpc85xx-cpufreq.o diff --git a/drivers/cpufreq/mpc85xx-cpufreq.c b/drivers/cpufreq/mpc85xx-cpufreq.c new file mode 100644 index 000..f56c826 --- /dev/null +++ b/drivers/cpufreq/mpc85xx-cpufreq.c @@ -0,0 +1,390 @@ +/* + * Copyright (C) 2008-2012 Freescale Semiconductor, Inc. + * Author: Dave Liu dave...@freescale.com + * Modifier: Chenhui Zhao chenhui.z...@freescale.com + * + * The cpufreq driver is for Freescale 85xx processor, + * based on arch/powerpc/platforms/cell/cbe_cpufreq.c + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 + * Christian Krafft kra...@de.ibm.com + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h +#include linux/cpufreq.h +#include linux/of_platform.h +#include linux/suspend.h +#include linux/cpu.h +#include linux/time.h +#include linux/io.h +#include linux/smp.h + +#include asm/prom.h +#include asm/reg.h +#include asm/machdep.h + +#include sysdev/fsl_soc.h + +static DEFINE_MUTEX(mpc85xx_switch_mutex); +static void __iomem *guts; + +static u32 sysfreq; +static unsigned int max_pll[2]; +static atomic_t in_jog_process; +static struct cpufreq_frequency_table *mpc85xx_freqs; +static int (*set_pll)(unsigned int cpu, unsigned int pll); + +static struct
[PATCH v2 08/15] powerpc/85xx: add cpu hotplug support for e500mc/e5500
From: Chen-Hui Zhao chenhui.z...@freescale.com Add support to disable and re-enable individual cores at runtime. This supports e500mc/e5500 core based SoCs. To prevent the register access race, only read/write RCPM registers in platform_cpu_die() on the boot cpu instead of accessing by individual cpus. Platform implementations can override the platform_cpu_die(). Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/smp.h|1 + arch/powerpc/kernel/smp.c | 16 ++- arch/powerpc/platforms/85xx/smp.c | 56 ++-- 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0e11a09..b6851be 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -347,7 +347,7 @@ config SWIOTLB config HOTPLUG_CPU bool Support for enabling/disabling CPUs depends on SMP HOTPLUG (PPC_PSERIES || \ - PPC_PMAC || PPC_POWERNV || (PPC_85xx !PPC_E500MC)) + PPC_PMAC || PPC_POWERNV || PPC_85xx) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 195ce2a..95be584 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -60,6 +60,7 @@ extern void smp_generic_take_timebase(void); DECLARE_PER_CPU(unsigned int, cpu_pvr); #ifdef CONFIG_HOTPLUG_CPU +void platform_cpu_die(unsigned int cpu); extern void migrate_irqs(void); int generic_cpu_disable(void); void generic_cpu_die(unsigned int cpu); diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 76bd9da..386c7ea 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -381,14 +381,28 @@ int generic_cpu_disable(void) return 0; } +/** + * platform_cpu_die() - do platform related operations on the boot cpu + * after CPU_DEAD is assigned to the variable cpu_state of the dying cpu. + * Platform implementations can override this. + * + * @cpu: the cpu to die + */ +void __attribute__ ((weak)) platform_cpu_die(unsigned int cpu) +{ + return; +} + void generic_cpu_die(unsigned int cpu) { int i; for (i = 0; i 100; i++) { smp_rmb(); - if (per_cpu(cpu_state, cpu) == CPU_DEAD) + if (per_cpu(cpu_state, cpu) == CPU_DEAD) { + platform_cpu_die(cpu); return; + } msleep(100); } printk(KERN_ERR CPU%d didn't die...\n, cpu); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 6c2fe6b..6eae2e0 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -40,7 +40,7 @@ struct epapr_spin_table { u32 pir; }; -static struct ccsr_guts __iomem *guts; +static void __iomem *guts_regs; static u64 timebase; static int tb_req; static int tb_valid; @@ -62,7 +62,7 @@ static inline u32 get_phy_cpu_mask(void) static void mpc85xx_timebase_freeze(int freeze) { - struct ccsr_rcpm __iomem *rcpm = (typeof(rcpm))guts; + struct ccsr_rcpm __iomem *rcpm = guts_regs; u32 mask = get_phy_cpu_mask(); if (freeze) @@ -76,6 +76,7 @@ static void mpc85xx_timebase_freeze(int freeze) #else static void mpc85xx_timebase_freeze(int freeze) { + struct ccsr_guts __iomem *guts = guts_regs; uint32_t mask; mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; @@ -84,6 +85,7 @@ static void mpc85xx_timebase_freeze(int freeze) else clrbits32(guts-devdisr, mask); + /* read back to push the previous write */ in_be32(guts-devdisr); } #endif @@ -128,7 +130,45 @@ static void mpc85xx_take_timebase(void) local_irq_restore(flags); } +static void core_reset_erratum(int hw_cpu) +{ +#ifdef CONFIG_PPC_E500MC + struct ccsr_rcpm __iomem *rcpm = guts_regs; + + clrbits32(rcpm-cnapcr, 1 hw_cpu); +#endif +} + #ifdef CONFIG_HOTPLUG_CPU +#ifdef CONFIG_PPC_E500MC +static void __cpuinit smp_85xx_mach_cpu_die(void) +{ + unsigned int cpu = smp_processor_id(); + + local_irq_disable(); + idle_task_exit(); + mb(); + + mtspr(SPRN_TCR, 0); + + __flush_disable_L1(); + disable_backside_L2_cache(); + + generic_set_cpu_dead(cpu); + + while (1); +} + +void platform_cpu_die(unsigned int cpu) +{ + unsigned int hw_cpu = get_hard_smp_processor_id(cpu); + struct ccsr_rcpm __iomem *rcpm = guts_regs; + + /* Core Nap Operation */ + setbits32(rcpm-cnapcr, 1 hw_cpu); +} +#else +/* for e500v1 and e500v2 */ static void __cpuinit smp_85xx_mach_cpu_die(void) { unsigned int cpu = smp_processor_id
[PATCH v2 09/15] powerpc/rcpm: add sleep feature for SoCs using RCPM
The SoCs which have a RCPM (Run Control/Power Management) module support power management feature. This patch implements sleep feature. In sleep mode, the clocks of cores and unused IP blocks will be turned off. The IP blocks which are allowed to wake up the system are still running. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/Kconfig|4 +- arch/powerpc/include/asm/fsl_guts.h |1 + arch/powerpc/platforms/85xx/Kconfig |1 + arch/powerpc/sysdev/Kconfig |5 ++ arch/powerpc/sysdev/Makefile|1 + arch/powerpc/sysdev/fsl_rcpm.c | 101 +++ 6 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/sysdev/fsl_rcpm.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index b6851be..0ad6e30 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -220,7 +220,7 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ - (PPC_85xx !PPC_E500MC) || PPC_86xx || PPC_PSERIES \ + FSL_SOC_BOOKE || PPC_86xx || PPC_PSERIES \ || 44x || 40x config PPC_DCR_NATIVE @@ -694,7 +694,7 @@ config FSL_PCI config FSL_PMC bool default y - depends on SUSPEND (PPC_85xx || PPC_86xx) + depends on SUSPEND ((PPC_85xx !PPC_E500MC) || PPC_86xx) help Freescale MPC85xx/MPC86xx power management controller support (suspend/resume). For MPC83xx see platforms/83xx/suspend.c diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index 4eac1cf..b8a08d5 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -124,6 +124,7 @@ struct ccsr_rcpm { u8 res0038[4]; __be32 cwdtdsr;/* 0x003c - Core watchdog detect status register */ __be32 powmgtcsr; /* 0x0040 - Power Mangement Control Status Register */ +#define RCPM_POWMGTCSR_SLP 0x0002 u8 res0044[12]; __be32 ippdexpcr; /* 0x0050 - IP Powerdown Exception Control Register */ u8 res0054[16]; diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 8f02b05..c0aa36e 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -8,6 +8,7 @@ menuconfig FSL_SOC_BOOKE select FSL_PCI if PCI select SERIAL_8250_EXTENDED if SERIAL_8250 select SERIAL_8250_SHARE_IRQ if SERIAL_8250 + select FSL_CORENET_RCPM if SUSPEND PPC_E500MC default y if FSL_SOC_BOOKE diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig index a84fecf..6c22d91 100644 --- a/arch/powerpc/sysdev/Kconfig +++ b/arch/powerpc/sysdev/Kconfig @@ -33,3 +33,8 @@ config SCOM_DEBUGFS config GE_FPGA bool default n + +config FSL_CORENET_RCPM + bool + help +This option enables support for RCPM (Run Control/Power Management). diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index b0a518e..f12b856 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) obj-$(CONFIG_FSL_PMC) += fsl_pmc.o +obj-$(CONFIG_FSL_CORENET_RCPM) += fsl_rcpm.o obj-$(CONFIG_FSL_LBC) += fsl_lbc.o obj-$(CONFIG_FSL_IFC) += fsl_ifc.o obj-$(CONFIG_FSL_GTM) += fsl_gtm.o diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c new file mode 100644 index 000..fd789da --- /dev/null +++ b/arch/powerpc/sysdev/fsl_rcpm.c @@ -0,0 +1,101 @@ +/* + * RCPM(Run Control/Power Management) support + * + * Copyright 2012-2013 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 linux/types.h +#include linux/errno.h +#include linux/suspend.h +#include linux/device.h +#include linux/delay.h +#include linux/of_platform.h + +#include asm/io.h +#include asm/cacheflush.h +#include asm/fsl_guts.h + +static struct ccsr_rcpm __iomem *rcpm_regs; + +static int rcpm_suspend_enter(suspend_state_t state) +{ + int ret = 0; + + switch (state) { + case PM_SUSPEND_STANDBY: + + flush_dcache_L1(); + flush_backside_L2_cache(); + + setbits32(rcpm_regs-powmgtcsr, RCPM_POWMGTCSR_SLP); + + /* At this point, the device is in sleep mode. */ + + /* Upon resume, wait for SLP bit
[PATCH v2 10/15] powerpc/85xx: fix 64-bit support for cpu hotplug
From: Chen-Hui Zhao chenhui.z...@freescale.com * The paca[cpu].cpu_start is used as a signal to indicate if the cpu should start. So it should be cleard in .cpu_die(). * The limit memory routine only needs to be ran once at boot time by the boot cpu. Prevent other cpus running it again. * Rearrange the code segment in smp_85xx_kick_cpu() to share codes between PPC64 and PPC32 as far as possible. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/Kconfig |2 +- arch/powerpc/kernel/smp.c |3 +++ arch/powerpc/mm/tlb_nohash.c |6 -- arch/powerpc/platforms/85xx/smp.c | 23 +++ 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0ad6e30..aa5794b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -347,7 +347,7 @@ config SWIOTLB config HOTPLUG_CPU bool Support for enabling/disabling CPUs depends on SMP HOTPLUG (PPC_PSERIES || \ - PPC_PMAC || PPC_POWERNV || PPC_85xx) + PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 386c7ea..c8aa739 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -401,6 +401,9 @@ void generic_cpu_die(unsigned int cpu) smp_rmb(); if (per_cpu(cpu_state, cpu) == CPU_DEAD) { platform_cpu_die(cpu); +#ifdef CONFIG_PPC64 + paca[cpu].cpu_start = 0; +#endif return; } msleep(100); diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index 6888cad..de7bf06 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c @@ -627,8 +627,10 @@ static void __early_init_mmu(int boot_cpu) num_cams = (mfspr(SPRN_TLB1CFG) TLBnCFG_N_ENTRY) / 4; linear_map_top = map_mem_in_cams(linear_map_top, num_cams); - /* limit memory so we dont have linear faults */ - memblock_enforce_memory_limit(linear_map_top); + if (boot_cpu) { + /* limit memory so we dont have linear faults */ + memblock_enforce_memory_limit(linear_map_top); + } patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e); patch_exception(0x1e0, exc_instruction_tlb_miss_bolted_book3e); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 6eae2e0..74d8cde 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -251,10 +251,6 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) spin_table = phys_to_virt(*cpu_rel_addr); local_irq_save(flags); -#ifdef CONFIG_PPC32 -#ifdef CONFIG_HOTPLUG_CPU - /* Corresponding to generic_set_cpu_dead() */ - generic_set_cpu_up(nr); if (system_state == SYSTEM_RUNNING) { /* @@ -298,12 +294,19 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) /* clear the acknowledge status */ __secondary_hold_acknowledge = -1; } -#endif flush_spin_table(spin_table); out_be32(spin_table-pir, hw_cpu); +#ifdef CONFIG_PPC32 out_be32(spin_table-addr_l, __pa(__early_start)); +#else + out_be32(spin_table-addr_h, + __pa(*(u64 *)generic_secondary_smp_init) 32); + out_be32(spin_table-addr_l, + __pa(*(u64 *)generic_secondary_smp_init) 0x); +#endif flush_spin_table(spin_table); +#ifdef CONFIG_PPC32 /* Wait a bit for the CPU to ack. */ if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu, 1, 100)) { @@ -312,18 +315,14 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) ret = -ENOENT; goto out; } -out: #else smp_generic_kick_cpu(nr); - - flush_spin_table(spin_table); - out_be32(spin_table-pir, hw_cpu); - out_be64((u64 *)(spin_table-addr_h), - __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); - flush_spin_table(spin_table); #endif + /* Corresponding to generic_set_cpu_dead() */ + generic_set_cpu_up(nr); cur_booting_core = hw_cpu; +out: local_irq_restore(flags); if (ioremappable) -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 07/15] powerpc/85xx: add time base sync for SoCs based on e500mc/e5500
From: Chen-Hui Zhao chenhui.z...@freescale.com In the case of SMP, during the time base sync period, all time bases of online cores must stop, then start simultaneously. There is a RCPM (Run Control/Power Management) module in CoreNet based SoCs. Define a struct ccsr_rcpm to describe the register map. This patch supports SoCs based on e500mc/e5500, such as P4080, P5020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/include/asm/fsl_guts.h | 38 +++ arch/powerpc/platforms/85xx/smp.c | 32 + 2 files changed, 70 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index 77ced0b..4eac1cf 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -106,6 +106,44 @@ struct ccsr_guts { /* Alternate function signal multiplex control */ #define MPC85xx_PMUXCR_QE(x) (0x8000 (x)) +struct ccsr_rcpm { + u8 res[4]; + __be32 cdozsr; /* 0x0004 - Core Doze Status Register */ + u8 res0008[4]; + __be32 cdozcr; /* 0x000c - Core Doze Control Register */ + u8 res0010[4]; + __be32 cnapsr; /* 0x0014 - Core Nap Status Register */ + u8 res0018[4]; + __be32 cnapcr; /* 0x001c - Core Nap Control Register */ + u8 res0020[4]; + __be32 cdozpsr;/* 0x0024 - Core Doze Previous Status Register */ + u8 res0028[4]; + __be32 cnappsr;/* 0x002c - Core Nap Previous Status Register */ + u8 res0030[4]; + __be32 cwaitsr;/* 0x0034 - Core Wait Status Register */ + u8 res0038[4]; + __be32 cwdtdsr;/* 0x003c - Core watchdog detect status register */ + __be32 powmgtcsr; /* 0x0040 - Power Mangement Control Status Register */ + u8 res0044[12]; + __be32 ippdexpcr; /* 0x0050 - IP Powerdown Exception Control Register */ + u8 res0054[16]; + __be32 cpmimr; /* 0x0064 - Core PM IRQ Mask Register */ + u8 res0068[4]; + __be32 cpmcimr;/* 0x006c - Core PM Critical IRQ Mask Register */ + u8 res0070[4]; + __be32 cpmmcmr;/* 0x0074 - Core PM Machine Check Mask Register */ + u8 res0078[4]; + __be32 cpmnmimr; /* 0x007c - Core PM NMI Mask Register */ + u8 res0080[4]; + __be32 ctbenr; /* 0x0084 - Core Time Base Enable Register */ + u8 res0088[4]; + __be32 ctbckselr; /* 0x008c - Core Time Base Clock Select Register */ + u8 res0090[4]; + __be32 ctbhltcr; /* 0x0094 - Core Time Base Halt Control Register */ + u8 res0098[4]; + __be32 cmcpmaskcr; /* 0x00a4 - Core machine check mask control register */ +}; + #ifdef CONFIG_PPC_86xx #define CCSR_GUTS_DMACR_DEV_SSI0 /* DMA controller/channel set to SSI */ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 6a17599..6c2fe6b 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -44,7 +44,36 @@ static struct ccsr_guts __iomem *guts; static u64 timebase; static int tb_req; static int tb_valid; +static u32 cur_booting_core; +#ifdef CONFIG_PPC_E500MC +/* get a physical mask of online cores and booting core */ +static inline u32 get_phy_cpu_mask(void) +{ + u32 mask; + int cpu; + + mask = 1 cur_booting_core; + for_each_online_cpu(cpu) + mask |= 1 get_hard_smp_processor_id(cpu); + + return mask; +} + +static void mpc85xx_timebase_freeze(int freeze) +{ + struct ccsr_rcpm __iomem *rcpm = (typeof(rcpm))guts; + u32 mask = get_phy_cpu_mask(); + + if (freeze) + clrbits32(rcpm-ctbenr, mask); + else + setbits32(rcpm-ctbenr, mask); + + /* read back to push the previos write */ + in_be32(rcpm-ctbenr); +} +#else static void mpc85xx_timebase_freeze(int freeze) { uint32_t mask; @@ -57,6 +86,7 @@ static void mpc85xx_timebase_freeze(int freeze) in_be32(guts-devdisr); } +#endif static void mpc85xx_give_timebase(void) { @@ -244,6 +274,7 @@ out: __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); flush_spin_table(spin_table); #endif + cur_booting_core = hw_cpu; local_irq_restore(flags); @@ -378,6 +409,7 @@ static const struct of_device_id mpc85xx_smp_guts_ids[] = { { .compatible = fsl,p1022-guts, }, { .compatible = fsl,p1023-guts, }, { .compatible = fsl,p2020-guts, }, + { .compatible = fsl,qoriq-rcpm-1.0, }, {}, }; -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org
[PATCH v2 11/15] powerpc/rcpm: add struct ccsr_rcpm_v2
From: Chen-Hui Zhao chenhui.z...@freescale.com Add struct ccsr_rcpm_v2 to descibe the v2 RCPM register map on some SoCs, such as T4240, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/include/asm/fsl_guts.h | 66 +++ 1 files changed, 66 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index b8a08d5..193d1f1 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -145,6 +145,72 @@ struct ccsr_rcpm { __be32 cmcpmaskcr; /* 0x00a4 - Core machine check mask control register */ }; +struct ccsr_rcpm_v2 { + u8 res_00[12]; + u32 tph10sr0; /* Thread PH10 Status Register */ + u8 res_10[12]; + u32 tph10setr0; /* Thread PH10 Set Control Register */ + u8 res_20[12]; + u32 tph10clrr0; /* Thread PH10 Clear Control Register */ + u8 res_30[12]; + u32 tph10psr0; /* Thread PH10 Previous Status Register */ + u8 res_40[12]; + u32 twaitsr0; /* Thread Wait Status Register */ + u8 res_50[96]; + u32 pcph15sr; /* Physical Core PH15 Status Register */ + u32 pcph15setr; /* Physical Core PH15 Set Control Register */ + u32 pcph15clrr; /* Physical Core PH15 Clear Control Register */ + u32 pcph15psr; /* Physical Core PH15 Prev Status Register */ + u8 res_c0[16]; + u32 pcph20sr; /* Physical Core PH20 Status Register */ + u32 pcph20setr; /* Physical Core PH20 Set Control Register */ + u32 pcph20clrr; /* Physical Core PH20 Clear Control Register */ + u32 pcph20psr; /* Physical Core PH20 Prev Status Register */ + u32 pcpw20sr; /* Physical Core PW20 Status Register */ + u8 res_e0[12]; + u32 pcph30sr; /* Physical Core PH30 Status Register */ + u32 pcph30setr; /* Physical Core PH30 Set Control Register */ + u32 pcph30clrr; /* Physical Core PH30 Clear Control Register */ + u32 pcph30psr; /* Physical Core PH30 Prev Status Register */ + u8 res_100[32]; + u32 ippwrgatecr;/* IP Power Gating Control Register */ + u8 res_124[12]; + u32 powmgtcsr; /* Power Management Control Status Reg */ +#define RCPM_POWMGTCSR_LPM20_RQ0x0010 +#define RCPM_POWMGTCSR_LPM20_ST0x0200 +#define RCPM_POWMGTCSR_P_LPM20_ST 0x0100 + u8 res_134[12]; + u32 ippdexpcr[4]; /* IP Powerdown Exception Control Reg */ + u8 res_150[12]; + u32 tpmimr0;/* Thread PM Interrupt Mask Reg */ + u8 res_160[12]; + u32 tpmcimr0; /* Thread PM Crit Interrupt Mask Reg */ + u8 res_170[12]; + u32 tpmmcmr0; /* Thread PM Machine Check Interrupt Mask Reg */ + u8 res_180[12]; + u32 tpmnmimr0; /* Thread PM NMI Mask Reg */ + u8 res_190[12]; + u32 tmcpmaskcr0;/* Thread Machine Check Mask Control Reg */ + u32 pctbenr;/* Physical Core Time Base Enable Reg */ + u32 pctbclkselr;/* Physical Core Time Base Clock Select */ + u32 tbclkdivr; /* Time Base Clock Divider Register */ + u8 res_1ac[4]; + u32 ttbhltcr[4];/* Thread Time Base Halt Control Register */ + u32 clpcl10sr; /* Cluster PCL10 Status Register */ + u32 clpcl10setr;/* Cluster PCL30 Set Control Register */ + u32 clpcl10clrr;/* Cluster PCL30 Clear Control Register */ + u32 clpcl10psr; /* Cluster PCL30 Prev Status Register */ + u32 cddslpsetr; /* Core Domain Deep Sleep Set Register */ + u32 cddslpclrr; /* Core Domain Deep Sleep Clear Register */ + u32 cdpwroksetr;/* Core Domain Power OK Set Register */ + u32 cdpwrokclrr;/* Core Domain Power OK Clear Register */ + u32 cdpwrensr; /* Core Domain Power Enable Status Register */ + u32 cddslsr;/* Core Domain Deep Sleep Status Register */ + u8 res_1e8[8]; + u32 dslpcntcr[8]; /* Deep Sleep Counter Cfg Register */ + u8 res_300[3568]; +}; + #ifdef CONFIG_PPC_86xx #define CCSR_GUTS_DMACR_DEV_SSI0 /* DMA controller/channel set to SSI */ -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 13/15] powerpc/85xx: add support for e6500 L1 cache operation
From: Chen-Hui Zhao chenhui.z...@freescale.com The L1 Data Cache of e6500 contains no modified data, no flush is required. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/kernel/fsl_booke_cache.S | 11 ++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/fsl_booke_cache.S b/arch/powerpc/kernel/fsl_booke_cache.S index 232c47b..24a52bb 100644 --- a/arch/powerpc/kernel/fsl_booke_cache.S +++ b/arch/powerpc/kernel/fsl_booke_cache.S @@ -65,13 +65,22 @@ _GLOBAL(flush_dcache_L1) blr +#define PVR_E6500 0x8040 + /* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ _GLOBAL(__flush_disable_L1) +/* L1 Data Cache of e6500 contains no modified data, no flush is required */ + mfspr r3, SPRN_PVR + rlwinm r4, r3, 16, 0x + lis r5, 0 + ori r5, r5, PVR_E6500@l + cmpwr4, r5 + beq 2f mflrr10 bl flush_dcache_L1 /* Flush L1 d-cache */ mtlrr10 - msync +2: msync mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ li r5, 2 rlwimi r4, r5, 0, 3 -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 14/15] powerpc/smp: add cpu hotplug support for e6500
From: Chen-Hui Zhao chenhui.z...@freescale.com * Only if two threads of one core are offline, the core can enter PH20 state. * Clear PH20 bits before core reset, or core will not restart. * Introduced a variable l2cache_type in the struce cpu_spec to indentify the type of L2 cache. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/include/asm/cputable.h | 10 arch/powerpc/kernel/cputable.c |5 arch/powerpc/platforms/85xx/smp.c | 40 +- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index f326444..3715def 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -33,6 +33,13 @@ enum powerpc_pmc_type { PPC_PMC_G4 = 3, }; +enum powerpc_l2cache_type { + PPC_L2_CACHE_DEFAULT = 0, + PPC_L2_CACHE_CORE= 1, /* L2 cache used exclusively by one core */ + PPC_L2_CACHE_CLUSTER = 2, /* L2 cache shared by a core cluster */ + PPC_L2_CACHE_SOC = 3, /* L2 cache shared by all cores */ +}; + struct pt_regs; extern int machine_check_generic(struct pt_regs *regs); @@ -58,6 +65,9 @@ struct cpu_spec { unsigned inticache_bsize; unsigned intdcache_bsize; + /* L2 cache type */ + enum powerpc_l2cache_type l2cache_type; + /* number of performance monitor counters */ unsigned intnum_pmcs; enum powerpc_pmc_type pmc_type; diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index cc39139..a7329c1 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -2004,6 +2004,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_e500v1, .machine_check = machine_check_e500, .platform = ppc8540, + .l2cache_type = PPC_L2_CACHE_SOC, }, { /* e500v2 */ .pvr_mask = 0x, @@ -2023,6 +2024,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_e500v2, .machine_check = machine_check_e500, .platform = ppc8548, + .l2cache_type = PPC_L2_CACHE_SOC, }, { /* e500mc */ .pvr_mask = 0x, @@ -2040,6 +2042,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_e500mc, .machine_check = machine_check_e500mc, .platform = ppce500mc, + .l2cache_type = PPC_L2_CACHE_CORE, }, #endif /* CONFIG_PPC32 */ { /* e5500 */ @@ -2061,6 +2064,7 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif .machine_check = machine_check_e500mc, .platform = ppce5500, + .l2cache_type = PPC_L2_CACHE_CORE, }, { /* e6500 */ .pvr_mask = 0x, @@ -2082,6 +2086,7 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif .machine_check = machine_check_e500mc, .platform = ppce6500, + .l2cache_type = PPC_L2_CACHE_CLUSTER, }, #ifdef CONFIG_PPC32 { /* default match */ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 5f3eee3..a8b4df7 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -166,13 +166,31 @@ static void core_reset_erratum(int hw_cpu) { #ifdef CONFIG_PPC_E500MC struct ccsr_rcpm __iomem *rcpm = guts_regs; + struct ccsr_rcpm_v2 __iomem *rcpm_v2 = guts_regs; - clrbits32(rcpm-cnapcr, 1 hw_cpu); + if (rcpmv2) + setbits32(rcpm_v2-pcph20clrr, + 1 cpu_core_index_of_thread(hw_cpu)); + else + clrbits32(rcpm-cnapcr, 1 hw_cpu); #endif } #ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_PPC_E500MC +static inline bool is_core_down(unsigned int thread) +{ + cpumask_t thd_mask; + + if (!smt_capable()) + return true; + + cpumask_shift_left(thd_mask, threads_core_mask, + cpu_core_index_of_thread(thread) * threads_per_core); + + return !cpumask_intersects(thd_mask, cpu_online_mask); +} + static void __cpuinit smp_85xx_mach_cpu_die(void) { unsigned int cpu = smp_processor_id(); @@ -183,8 +201,11 @@ static void __cpuinit smp_85xx_mach_cpu_die(void) mtspr(SPRN_TCR, 0); - __flush_disable_L1(); - disable_backside_L2_cache
[PATCH v2 15/15] powerpc/rcpm: add sleep support for T4/B4 chips
From: Chen-Hui Zhao chenhui.z...@freescale.com RCPM unit controls the power managment of T4/B4 chips. Software can access RCPM registers to put specific thread/core in PH10/PH15/PH20/PH30 state or put the device in LPM10/LPM20/LPM40 mode. The RCPM unit supports several wake up sources through internal timers and internal and external interrupts. When the device enter sleep state, it will be put in LPM20 mode. The command is echo standby /sys/power/state. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/sysdev/fsl_rcpm.c | 54 +--- 1 files changed, 50 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c index fd789da..10e5cb3 100644 --- a/arch/powerpc/sysdev/fsl_rcpm.c +++ b/arch/powerpc/sysdev/fsl_rcpm.c @@ -20,6 +20,7 @@ #include asm/fsl_guts.h static struct ccsr_rcpm __iomem *rcpm_regs; +static struct ccsr_rcpm_v2 __iomem *rcpm2_regs; static int rcpm_suspend_enter(suspend_state_t state) { @@ -53,6 +54,41 @@ static int rcpm_suspend_enter(suspend_state_t state) return ret; } +static int rcpm_v2_suspend_enter(suspend_state_t state) +{ + int ret = 0; + + switch (state) { + case PM_SUSPEND_STANDBY: + + /* clear previous LPM20 status */ + setbits32(rcpm2_regs-powmgtcsr, RCPM_POWMGTCSR_P_LPM20_ST); + /* enter LPM20 status */ + setbits32(rcpm2_regs-powmgtcsr, RCPM_POWMGTCSR_LPM20_RQ); + + /* At this point, the device is in LPM20 status. */ + + /* resume ... */ + ret = spin_event_timeout( + (in_be32(rcpm2_regs-powmgtcsr) RCPM_POWMGTCSR_LPM20_ST) + == 0, 1, 10); + if (!ret) { + pr_err(%s: timeout waiting for LPM20 bit to be cleared\n, + __func__); + ret = -EINVAL; + } + + break; + + default: + ret = -EINVAL; + + } + + return ret; + +} + static int rcpm_suspend_valid(suspend_state_t state) { if (state == PM_SUSPEND_STANDBY) @@ -63,16 +99,25 @@ static int rcpm_suspend_valid(suspend_state_t state) static const struct platform_suspend_ops rcpm_suspend_ops = { .valid = rcpm_suspend_valid, - .enter = rcpm_suspend_enter, }; static int rcpm_probe(struct platform_device *pdev) { struct device_node *np = pdev-dev.of_node; - rcpm_regs = of_iomap(np, 0); - if (!rcpm_regs) - return -ENOMEM; + if (of_device_is_compatible(np, fsl,qoriq-rcpm-2.0)) { + rcpm2_regs = of_iomap(np, 0); + if (!rcpm2_regs) + return -ENOMEM; + + rcpm_suspend_ops.enter = rcpm_v2_suspend_enter; + } else { + rcpm_regs = of_iomap(np, 0); + if (!rcpm_regs) + return -ENOMEM; + + rcpm_suspend_ops.enter = rcpm_suspend_enter; + } suspend_set_ops(rcpm_suspend_ops); @@ -82,6 +127,7 @@ static int rcpm_probe(struct platform_device *pdev) static const struct of_device_id rcpm_ids[] = { { .compatible = fsl,qoriq-rcpm-1.0, }, + { .compatible = fsl,qoriq-rcpm-2.0, }, { }, }; -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 12/15] powerpc/85xx: add time base sync support for e6500
From: Chen-Hui Zhao chenhui.z...@freescale.com For e6500, two threads in one core share one time base. Just need to do time base sync on first thread of one core, and skip it on the other thread. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/platforms/85xx/smp.c | 52 +++- 1 files changed, 44 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 74d8cde..5f3eee3 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -26,6 +26,7 @@ #include asm/cacheflush.h #include asm/dbell.h #include asm/fsl_guts.h +#include asm/cputhreads.h #include sysdev/fsl_soc.h #include sysdev/mpic.h @@ -45,6 +46,7 @@ static u64 timebase; static int tb_req; static int tb_valid; static u32 cur_booting_core; +static bool rcpmv2; #ifdef CONFIG_PPC_E500MC /* get a physical mask of online cores and booting core */ @@ -53,26 +55,40 @@ static inline u32 get_phy_cpu_mask(void) u32 mask; int cpu; - mask = 1 cur_booting_core; - for_each_online_cpu(cpu) - mask |= 1 get_hard_smp_processor_id(cpu); + if (smt_capable()) { + /* two threads in one core share one time base */ + mask = 1 cpu_core_index_of_thread(cur_booting_core); + for_each_online_cpu(cpu) + mask |= 1 cpu_core_index_of_thread( + get_hard_smp_processor_id(cpu)); + } else { + mask = 1 cur_booting_core; + for_each_online_cpu(cpu) + mask |= 1 get_hard_smp_processor_id(cpu); + } return mask; } static void mpc85xx_timebase_freeze(int freeze) { - struct ccsr_rcpm __iomem *rcpm = guts_regs; + u32 *addr; u32 mask = get_phy_cpu_mask(); + if (rcpmv2) + addr = ((struct ccsr_rcpm_v2 *)guts_regs)-pctbenr; + else + addr = ((struct ccsr_rcpm *)guts_regs)-ctbenr; + if (freeze) - clrbits32(rcpm-ctbenr, mask); + clrbits32(addr, mask); else - setbits32(rcpm-ctbenr, mask); + setbits32(addr, mask); - /* read back to push the previos write */ - in_be32(rcpm-ctbenr); + /* read back to push the previous write */ + in_be32(addr); } + #else static void mpc85xx_timebase_freeze(int freeze) { @@ -94,6 +110,16 @@ static void mpc85xx_give_timebase(void) { unsigned long flags; +#ifdef CONFIG_PPC_E500MC + /* +* If the booting thread is not the first thread of the core, +* skip time base sync. +*/ + if (smt_capable() + cur_booting_core != cpu_first_thread_sibling(cur_booting_core)) + return; +#endif + local_irq_save(flags); while (!tb_req) @@ -117,6 +143,12 @@ static void mpc85xx_take_timebase(void) { unsigned long flags; +#ifdef CONFIG_PPC_E500MC + if (smt_capable() + cur_booting_core != cpu_first_thread_sibling(cur_booting_core)) + return; +#endif + local_irq_save(flags); tb_req = 1; @@ -457,6 +489,7 @@ static const struct of_device_id mpc85xx_smp_guts_ids[] = { { .compatible = fsl,p1023-guts, }, { .compatible = fsl,p2020-guts, }, { .compatible = fsl,qoriq-rcpm-1.0, }, + { .compatible = fsl,qoriq-rcpm-2.0, }, {}, }; @@ -483,6 +516,9 @@ void __init mpc85xx_smp_init(void) np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); if (np) { + if (of_device_is_compatible(np, fsl,qoriq-rcpm-2.0)) + rcpmv2 = true; + guts_regs = of_iomap(np, 0); of_node_put(np); if (!guts_regs) { -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 06/15] powerpc/85xx: add support to JOG feature using cpufreq interface
On Mon, Apr 22, 2013 at 08:55:35AM +0530, Viresh Kumar wrote: On Fri, Apr 19, 2013 at 4:17 PM, Zhao Chenhui chenhui.z...@freescale.com wrote: diff --git a/drivers/cpufreq/mpc85xx-cpufreq.c b/drivers/cpufreq/mpc85xx-cpufreq.c +#include linux/module.h +#include linux/cpufreq.h +#include linux/of_platform.h +#include linux/suspend.h +#include linux/cpu.h +#include linux/time.h +#include linux/io.h +#include linux/smp.h Would be better to keep them in alphabetical order, so that we don't add anything twice. Good idea. +static int mpc85xx_cpufreq_cpu_init(struct cpufreq_policy *policy) +{ + unsigned int i, cur_pll; + int hw_cpu = get_hard_smp_processor_id(policy-cpu); + + if (!cpu_present(policy-cpu)) This can't happen and so no need to check it. + return -ENODEV; + + /* the latency of a transition, the unit is ns */ + policy-cpuinfo.transition_latency = 2000; + + cur_pll = get_pll(hw_cpu); + + /* initialize frequency table */ + pr_debug(core%d frequency table:\n, hw_cpu); + for (i = 0; mpc85xx_freqs[i].frequency != CPUFREQ_TABLE_END; i++) { + if (mpc85xx_freqs[i].index = max_pll[hw_cpu]) { + /* The frequency unit is kHz. */ + mpc85xx_freqs[i].frequency = + (sysfreq * mpc85xx_freqs[i].index / 2) / 1000; + } else { + mpc85xx_freqs[i].frequency = CPUFREQ_ENTRY_INVALID; + } + + pr_debug(%d: %dkHz\n, i, mpc85xx_freqs[i].frequency); + + if (mpc85xx_freqs[i].index == cur_pll) + policy-cur = mpc85xx_freqs[i].frequency; + } + pr_debug(current pll is at %d, and core freq is%d\n, + cur_pll, policy-cur); + + cpufreq_frequency_table_get_attr(mpc85xx_freqs, policy-cpu); + + /* +* This ensures that policy-cpuinfo_min +* and policy-cpuinfo_max are set correctly. +*/ + return cpufreq_frequency_table_cpuinfo(policy, mpc85xx_freqs); Call cpufreq_frequency_table_get_attr() at the end after above call is successful. +} +static int mpc85xx_cpufreq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) merge above two lines. +{ + struct cpufreq_freqs freqs; + unsigned int new; + int ret = 0; + + if (!set_pll) + return -ENODEV; + + cpufreq_frequency_table_target(policy, + mpc85xx_freqs, + target_freq, + relation, + new); same.. merge all above to put it in a single line. + freqs.old = policy-cur; + freqs.new = mpc85xx_freqs[new].frequency; + freqs.cpu = policy-cpu; not required now. + mutex_lock(mpc85xx_switch_mutex); + cpufreq_notify_transition(freqs, CPUFREQ_PRECHANGE); ditto. Rebase over latest code from linux-next. This call has changed. + ret = set_pll(policy-cpu, mpc85xx_freqs[new].index); + if (!ret) { + pr_info(cpufreq: Setting core%d frequency to %d kHz and PLL ratio to %d:2\n, +policy-cpu, mpc85xx_freqs[new].frequency, +mpc85xx_freqs[new].index); + + ppc_proc_freq = freqs.new * 1000ul; + } + cpufreq_notify_transition(freqs, CPUFREQ_POSTCHANGE); + mutex_unlock(mpc85xx_switch_mutex); + + return ret; +} +static int __init mpc85xx_jog_init(void) +{ + struct device_node *np; + unsigned int svr; + + np = of_find_matching_node(NULL, mpc85xx_jog_ids); + if (!np) + return -ENODEV; + + guts = of_iomap(np, 0); + if (!guts) { + of_node_put(np); + return -ENODEV; + } + + sysfreq = fsl_get_sys_freq(); + + if (of_device_is_compatible(np, fsl,mpc8536-guts)) { + svr = mfspr(SPRN_SVR); + if ((svr 0x7fff) == 0x10) { + pr_err(MPC8536 Rev 1.0 does not support cpufreq(JOG).\n); + of_node_put(np); unmap too?? + return -ENODEV; + } + mpc85xx_freqs = mpc8536_freqs_table; + set_pll = mpc8536_set_pll; + max_pll[0] = get_pll(0); + + } else if (of_device_is_compatible(np, fsl,p1022-guts)) { + mpc85xx_freqs = p1022_freqs_table; + set_pll = p1022_set_pll; + max_pll[0] = get_pll(0); + max_pll[1] = get_pll(1
Re: [PATCH v2 06/15] powerpc/85xx: add support to JOG feature using cpufreq interface
On Mon, Apr 22, 2013 at 01:43:29AM +0200, Rafael J. Wysocki wrote: On Friday, April 19, 2013 07:00:57 PM Zhao Chenhui wrote: - Forwarded message from Zhao Chenhui chenhui.z...@freescale.com - Date: Fri, 19 Apr 2013 18:47:39 +0800 From: Zhao Chenhui chenhui.z...@freescale.com To: linuxppc-dev@lists.ozlabs.org CC: linux-ker...@vger.kernel.org Subject: [linuxppc-release] [PATCH v2 06/15] powerpc/85xx: add support to JOG feature using cpufreq interface X-Mailer: git-send-email 1.7.3 From: chenhui zhao chenhui.z...@freescale.com Some 85xx silicons like MPC8536 and P1022 have a JOG feature, which provides a dynamic mechanism to lower or raise the CPU core clock at runtime. This patch adds the support to change CPU frequency using the standard cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2, 2:1, 5:2, 3:1, 7:2 and 4:1. Two CPU cores on P1022 must not in the low power state during the frequency transition. The driver uses a atomic counter to meet the requirement. The jog mode frequency transition process on the MPC8536 is similar to the deep sleep process. The driver need save the CPU state and restore it after CPU warm reset. Note: * The I/O peripherals such as PCIe and eTSEC may lose packets during the jog mode frequency transition. * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum. Subsequent revisions of MPC8536 have corrected the erratum. Signed-off-by: Dave Liu dave...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Jerry Huang chang-ming.hu...@freescale.com Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com CC: Scott Wood scottw...@freescale.com Well, I'd like someone from the PowerPC camp to comment on this before I take it. Thanks, Rafael OK. Thanks. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [linuxppc-release] [PATCH v2 01/15] powerpc/85xx: cache operations for Freescale SoCs based on BOOK3E
Hi Kumar, Scott, Do you have any comments on this set of patches? Best Regards, -Chenhui On Fri, Apr 19, 2013 at 06:47:34PM +0800, Zhao Chenhui wrote: These cache operations support Freescale SoCs based on BOOK3E. Move L1 cache operations to fsl_booke_cache.S in order to maintain easily. And, add cache operations for backside L2 cache and platform cache. The backside L2 cache appears on e500mc and e5500 core. The platform cache supported by this patch is L2 Look-Aside Cache, which appears on SoCs with e500v1/e500v2 core, such as MPC8572, P1020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/include/asm/cacheflush.h |8 ++ arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/fsl_booke_cache.S | 210 + arch/powerpc/kernel/head_fsl_booke.S | 74 4 files changed, 219 insertions(+), 74 deletions(-) create mode 100644 arch/powerpc/kernel/fsl_booke_cache.S ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 01/15] powerpc/85xx: cache operations for Freescale SoCs based on BOOK3E
On Tue, Apr 23, 2013 at 06:46:10PM -0500, Scott Wood wrote: On 04/19/2013 05:47:34 AM, Zhao Chenhui wrote: These cache operations support Freescale SoCs based on BOOK3E. Move L1 cache operations to fsl_booke_cache.S in order to maintain easily. And, add cache operations for backside L2 cache and platform cache. The backside L2 cache appears on e500mc and e5500 core. The platform cache supported by this patch is L2 Look-Aside Cache, which appears on SoCs with e500v1/e500v2 core, such as MPC8572, P1020, etc. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/include/asm/cacheflush.h |8 ++ arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/fsl_booke_cache.S | 210 + arch/powerpc/kernel/head_fsl_booke.S | 74 4 files changed, 219 insertions(+), 74 deletions(-) create mode 100644 arch/powerpc/kernel/fsl_booke_cache.S diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index b843e35..bc3f937 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -32,6 +32,14 @@ extern void flush_dcache_page(struct page *page); extern void __flush_disable_L1(void); +#ifdef CONFIG_FSL_SOC_BOOKE +void flush_dcache_L1(void); +void flush_backside_L2_cache(void); +void disable_backside_L2_cache(void); +void flush_disable_L2(void); +void invalidate_enable_L2(void); +#endif Don't ifdef prototypes unless there's a good reason, such as providing an inline alternative. I'll get rid of this #ifdef. Why do you have flush_backside_L2_cache and disable_backside_L2_cache as something different from flush_disable_L2? The latter should flush whatever L2 is present. Don't treat pre-corenet as the default. These L2 caches are very different. The backside L2 is integrated in the e500mc/e5500 core and controlled by SPR registers. But, the latter L2 cache is on the SoC and controlled by registers mapped in CCSR. Why do we even need to distinguish L1 from L2 at all? Shouldn't the function that gets exposed just be flush and disable data caches that are specific to this cpu? What should happen on e6500? -Scott Yes. It is a good idea to use a set of uniform functions to operate the caches of e500/e500mc/e5500/e6500 and SoCs. I'll think over your comments. Thanks for you comments. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 13/15] powerpc/85xx: add support for e6500 L1 cache operation
On Tue, Apr 23, 2013 at 07:00:49PM -0500, Scott Wood wrote: On 04/19/2013 05:47:46 AM, Zhao Chenhui wrote: From: Chen-Hui Zhao chenhui.z...@freescale.com The L1 Data Cache of e6500 contains no modified data, no flush is required. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/kernel/fsl_booke_cache.S | 11 ++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/fsl_booke_cache.S b/arch/powerpc/kernel/fsl_booke_cache.S index 232c47b..24a52bb 100644 --- a/arch/powerpc/kernel/fsl_booke_cache.S +++ b/arch/powerpc/kernel/fsl_booke_cache.S @@ -65,13 +65,22 @@ _GLOBAL(flush_dcache_L1) blr +#define PVR_E6500 0x8040 + /* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ _GLOBAL(__flush_disable_L1) +/* L1 Data Cache of e6500 contains no modified data, no flush is required */ +mfspr r3, SPRN_PVR +rlwinm r4, r3, 16, 0x +lis r5, 0 +ori r5, r5, PVR_E6500@l +cmpwr4, r5 +beq 2f mflrr10 bl flush_dcache_L1 /* Flush L1 d-cache */ mtlrr10 -msync +2: msync mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ li r5, 2 rlwimi r4, r5, 0, 3 Note that disabling the cache is a core operation, rather than a thread operation. Is this only called when the second thread is disabled? -Scott It is called only when a core is down. I can add a comment in the code. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 12/15] powerpc/85xx: add time base sync support for e6500
On Tue, Apr 23, 2013 at 07:04:06PM -0500, Scott Wood wrote: On 04/19/2013 05:47:45 AM, Zhao Chenhui wrote: From: Chen-Hui Zhao chenhui.z...@freescale.com For e6500, two threads in one core share one time base. Just need to do time base sync on first thread of one core, and skip it on the other thread. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/platforms/85xx/smp.c | 52 +++- 1 files changed, 44 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 74d8cde..5f3eee3 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -26,6 +26,7 @@ #include asm/cacheflush.h #include asm/dbell.h #include asm/fsl_guts.h +#include asm/cputhreads.h #include sysdev/fsl_soc.h #include sysdev/mpic.h @@ -45,6 +46,7 @@ static u64 timebase; static int tb_req; static int tb_valid; static u32 cur_booting_core; +static bool rcpmv2; #ifdef CONFIG_PPC_E500MC /* get a physical mask of online cores and booting core */ @@ -53,26 +55,40 @@ static inline u32 get_phy_cpu_mask(void) u32 mask; int cpu; -mask = 1 cur_booting_core; -for_each_online_cpu(cpu) -mask |= 1 get_hard_smp_processor_id(cpu); +if (smt_capable()) { +/* two threads in one core share one time base */ +mask = 1 cpu_core_index_of_thread(cur_booting_core); +for_each_online_cpu(cpu) +mask |= 1 cpu_core_index_of_thread( +get_hard_smp_processor_id(cpu)); +} else { +mask = 1 cur_booting_core; +for_each_online_cpu(cpu) +mask |= 1 get_hard_smp_processor_id(cpu); +} Where is smt_capable defined()? I assume somewhere in the patchset but it's a pain to search 12 patches... It is defined in arch/powerpc/include/asm/topology.h. #define smt_capable() (cpu_has_feature(CPU_FTR_SMT)) Thanks for your review again. Is this really about whether we're SMT-capable or whether we have rcpm v2? -Scott I think this if statement can be removed. The cpu_core_index_of_thread() can return the correct cpu number with thread or without thread. Like this: static inline u32 get_phy_cpu_mask(void) { u32 mask; int cpu; mask = 1 cpu_core_index_of_thread(cur_booting_core); for_each_online_cpu(cpu) mask |= 1 cpu_core_index_of_thread( get_hard_smp_processor_id(cpu)); return mask; } -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 12/15] powerpc/85xx: add time base sync support for e6500
On Wed, Apr 24, 2013 at 05:38:16PM -0500, Scott Wood wrote: On 04/24/2013 06:29:29 AM, Zhao Chenhui wrote: On Tue, Apr 23, 2013 at 07:04:06PM -0500, Scott Wood wrote: On 04/19/2013 05:47:45 AM, Zhao Chenhui wrote: From: Chen-Hui Zhao chenhui.z...@freescale.com For e6500, two threads in one core share one time base. Just need to do time base sync on first thread of one core, and skip it on the other thread. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/platforms/85xx/smp.c | 52 +++- 1 files changed, 44 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 74d8cde..5f3eee3 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -53,26 +55,40 @@ static inline u32 get_phy_cpu_mask(void) u32 mask; int cpu; - mask = 1 cur_booting_core; - for_each_online_cpu(cpu) - mask |= 1 get_hard_smp_processor_id(cpu); + if (smt_capable()) { + /* two threads in one core share one time base */ + mask = 1 cpu_core_index_of_thread(cur_booting_core); + for_each_online_cpu(cpu) + mask |= 1 cpu_core_index_of_thread( + get_hard_smp_processor_id(cpu)); + } else { + mask = 1 cur_booting_core; + for_each_online_cpu(cpu) + mask |= 1 get_hard_smp_processor_id(cpu); + } Where is smt_capable defined()? I assume somewhere in the patchset but it's a pain to search 12 patches... It is defined in arch/powerpc/include/asm/topology.h. #define smt_capable() (cpu_has_feature(CPU_FTR_SMT)) Thanks for your review again. We shouldn't base it on CPU_FTR_SMT. For example, e6500 doesn't claim that feature yet, except in our SDK kernel. That doesn't change the topology of CPU numbering. Then, where can I get the thread information? dts? Or, wait for upstream of the thread suppport of e6500. Is this really about whether we're SMT-capable or whether we have rcpm v2? -Scott I think this if statement can be removed. The cpu_core_index_of_thread() can return the correct cpu number with thread or without thread. Like this: static inline u32 get_phy_cpu_mask(void) { u32 mask; int cpu; mask = 1 cpu_core_index_of_thread(cur_booting_core); for_each_online_cpu(cpu) mask |= 1 cpu_core_index_of_thread( get_hard_smp_processor_id(cpu)); return mask; } Likewise, this will get it wrong if SMT is disabled or not yet implemented on a core. -Scott Let's look into cpu_core_index_of_thread() in arch/powerpc/kernel/smp.c. int cpu_core_index_of_thread(int cpu) { return cpu threads_shift; } If no thread, the threads_shift is equal to 0. It can work with no thread. Perhaps, I should submit this patch after the thread patches for e6500. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 12/15] powerpc/85xx: add time base sync support for e6500
On Thu, Apr 25, 2013 at 07:07:24PM -0500, Scott Wood wrote: On 04/24/2013 07:28:18 PM, Zhao Chenhui wrote: On Wed, Apr 24, 2013 at 05:38:16PM -0500, Scott Wood wrote: On 04/24/2013 06:29:29 AM, Zhao Chenhui wrote: On Tue, Apr 23, 2013 at 07:04:06PM -0500, Scott Wood wrote: On 04/19/2013 05:47:45 AM, Zhao Chenhui wrote: From: Chen-Hui Zhao chenhui.z...@freescale.com For e6500, two threads in one core share one time base. Just need to do time base sync on first thread of one core, and skip it on the other thread. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Andy Fleming aflem...@freescale.com --- arch/powerpc/platforms/85xx/smp.c | 52 +++- 1 files changed, 44 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 74d8cde..5f3eee3 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -53,26 +55,40 @@ static inline u32 get_phy_cpu_mask(void) u32 mask; int cpu; - mask = 1 cur_booting_core; - for_each_online_cpu(cpu) - mask |= 1 get_hard_smp_processor_id(cpu); + if (smt_capable()) { + /* two threads in one core share one time base */ + mask = 1 cpu_core_index_of_thread(cur_booting_core); + for_each_online_cpu(cpu) + mask |= 1 cpu_core_index_of_thread( + get_hard_smp_processor_id(cpu)); + } else { + mask = 1 cur_booting_core; + for_each_online_cpu(cpu) + mask |= 1 get_hard_smp_processor_id(cpu); + } Where is smt_capable defined()? I assume somewhere in the patchset but it's a pain to search 12 patches... It is defined in arch/powerpc/include/asm/topology.h. #define smt_capable() (cpu_has_feature(CPU_FTR_SMT)) Thanks for your review again. We shouldn't base it on CPU_FTR_SMT. For example, e6500 doesn't claim that feature yet, except in our SDK kernel. That doesn't change the topology of CPU numbering. Then, where can I get the thread information? dts? Or, wait for upstream of the thread suppport of e6500. It's an inherent property of e6500 (outside of some virtualization scenarios, but you wouldn't run this code under a hypervisor) that you have two threads per core (whether Linux uses them or not). Or you could read TMCFG0[NTHRD] if you know you're on a chip that has TMRs but aren't positive it's an e6500, but I wouldn't bother. If we do ever have such a chip, there are probably other things that will need updating. But how to know that there are TMRs on a chip except by CPU_FTR_SMT. static inline u32 get_phy_cpu_mask(void) { u32 mask; int cpu; mask = 1 cpu_core_index_of_thread(cur_booting_core); for_each_online_cpu(cpu) mask |= 1 cpu_core_index_of_thread( get_hard_smp_processor_id(cpu)); return mask; } Likewise, this will get it wrong if SMT is disabled or not yet implemented on a core. -Scott Let's look into cpu_core_index_of_thread() in arch/powerpc/kernel/smp.c. int cpu_core_index_of_thread(int cpu) { return cpu threads_shift; } If no thread, the threads_shift is equal to 0. It can work with no thread. My point is that if threads are disabled, threads_shift will be 0, but e6500 cores will still be numbered 0, 2, 4, etc. Perhaps, I should submit this patch after the thread patches for e6500. Why? -Scott Even if threads are disabled, the threads_shift derived from dts is right. But, if there aren't the thread related patches existed in SDK, the threads_shift gets a wrong value on T4. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 02/15] powerpc/85xx: add sleep and deep sleep support
On Tue, Apr 23, 2013 at 06:53:20PM -0500, Scott Wood wrote: On 04/19/2013 05:47:35 AM, Zhao Chenhui wrote: static int pmc_suspend_enter(suspend_state_t state) { -int ret; +int ret = 0; + +switch (state) { +#ifdef CONFIG_PPC_85xx +case PM_SUSPEND_MEM: +#ifdef CONFIG_SPE +enable_kernel_spe(); +#endif +enable_kernel_fp(); Why does enable_kernel_spe() need an ifdef but enable_kernel_fp() doesn't? will enclose it with CONFIG_PPC_FPU. +case PM_SUSPEND_STANDBY: +#ifdef CONFIG_FSL_SOC_BOOKE +flush_dcache_L1(); +#endif +setbits32(pmc_regs-powmgtcsr, POWMGTCSR_SLP); Only L1, even on e500mc? -Scott This patch is just for chips with pmc unit. They have no e500mc core. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/mpic: fix irq distribution problem when MPIC_SINGLE_DEST_CPU
For the mpic with a flag MPIC_SINGLE_DEST_CPU, only one bit should be set in interrupt destination registers. The code is applicable to 64-bit platforms as well as 32-bit. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/sysdev/mpic.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 0a13ecb..3cc2f91 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -54,7 +54,7 @@ static DEFINE_RAW_SPINLOCK(mpic_lock); #ifdef CONFIG_PPC32/* XXX for now */ #ifdef CONFIG_IRQ_ALL_CPUS -#define distribute_irqs(!(mpic-flags MPIC_SINGLE_DEST_CPU)) +#define distribute_irqs(1) #else #define distribute_irqs(0) #endif @@ -1703,7 +1703,7 @@ void mpic_setup_this_cpu(void) * it differently, then we should make sure we also change the default * values of irq_desc[].affinity in irq.c. */ - if (distribute_irqs) { + if (distribute_irqs !(mpic-flags MPIC_SINGLE_DEST_CPU)) { for (i = 0; i mpic-num_sources ; i++) mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk); -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/sysfs: disable hotplug for the boot cpu
Some features depend on the boot cpu, for instance, hibernate/suspend. So disable hotplug for the boot cpu. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com --- arch/powerpc/kernel/sysfs.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index e68a845..294b1c4e 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -655,8 +655,10 @@ static int __init topology_init(void) * CPU. For instance, the boot cpu might never be valid * for hotplugging. */ - if (ppc_md.cpu_die) + if (ppc_md.cpu_die cpu != boot_cpuid) c-hotpluggable = 1; + else + c-hotpluggable = 0; if (cpu_online(cpu) || c-hotpluggable) { register_cpu(c, cpu); -- 1.7.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/sysfs: disable hotplug for the boot cpu
On Wed, Jun 12, 2013 at 01:25:22PM +1000, Benjamin Herrenschmidt wrote: On Mon, 2013-06-03 at 18:43 +0800, Zhao Chenhui wrote: On Sat, Jun 01, 2013 at 07:49:44AM +1000, Benjamin Herrenschmidt wrote: On Tue, 2013-05-28 at 15:59 +0800, Zhao Chenhui wrote: Some features depend on the boot cpu, for instance, hibernate/suspend. So disable hotplug for the boot cpu. Don't we have code to move the boot CPU around when that happens ? Ben. Currently, the code in generic_cpu_disable() likes this: if (cpu == boot_cpuid) return -EBUSY; But the code in pseries/hotplug-cpu.c doesn't, we just move the boot CPU around when that happens. Any reason we can't do that generically ? Cheers, Ben. Some multicore SoCs firstly boot up the cpu0 after warm reset. In some suspend/resume cases, SoC will do a warm reset when resuming. In order to ensure that the suspending and resuming is running on a same cpu, cpu0 should be the last cpu to suspend. Here, cpu0 is the boot_cpuid. -Chenhui If the dying cpu is the boot cpu, it will return -EBUSY. In the subsequent error handling, cpu_notify_nofail(CPU_DOWN_FAILED) in _cpu_down() will be called. Unfortunately, some cpu notifier callbacks handled CPU_DOWN_PREPARE, but not CPU_DOWN_FAILED, such as sched_cpu_inactive(). So it will cause issues. If we set the hotpluggable for the boot cpu, we can prevent user applications from disabling the boot cpu. -Chenhui ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] mpic: fix Destination Registers init problem
The Freescale implementation of the MPIC only allows a single CPU destination for non-IPI interrupts. Test the flag MPIC_SINGLE_DEST_CPU to check if the Destination registers should be set. This prevents more than one bit is set at secondary processors initilizing time if the flag MPIC_SINGLE_DEST_CPU is set. Signed-off-by: Zhao Chenhui chenhui.z...@freescale.com Signed-off-by: Li Yang le...@freescale.com --- arch/powerpc/sysdev/mpic.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9c6e535..cc537f8 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1675,7 +1675,7 @@ void mpic_setup_this_cpu(void) * it differently, then we should make sure we also change the default * values of irq_desc[].affinity in irq.c. */ - if (distribute_irqs) { + if (distribute_irqs !(mpic-flags MPIC_SINGLE_DEST_CPU)) { for (i = 0; i mpic-num_sources ; i++) mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk); -- 1.7.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev