[PATCH v5 1/5] powerpc/85xx: implement hardware timebase sync

2012-05-11 Thread Zhao Chenhui
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

2012-05-11 Thread Zhao Chenhui
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

2012-05-11 Thread Zhao Chenhui
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

2012-05-11 Thread Zhao Chenhui
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

2012-06-04 Thread Zhao Chenhui
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

2012-06-04 Thread Zhao Chenhui
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

2012-06-04 Thread Zhao Chenhui
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

2012-06-05 Thread Zhao Chenhui
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

2012-06-05 Thread Zhao Chenhui
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

2012-06-05 Thread Zhao Chenhui
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

2012-06-05 Thread Zhao Chenhui
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

2012-06-06 Thread Zhao Chenhui
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

2012-06-06 Thread Zhao Chenhui
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

2012-06-06 Thread Zhao Chenhui
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

2012-06-06 Thread Zhao Chenhui
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

2012-06-26 Thread Zhao Chenhui
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

2012-06-26 Thread Zhao Chenhui
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

2012-06-26 Thread Zhao Chenhui
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

2012-06-26 Thread Zhao Chenhui
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

2012-06-26 Thread Zhao Chenhui
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

2012-06-27 Thread Zhao Chenhui
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

2012-06-27 Thread Zhao Chenhui
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

2012-06-27 Thread Zhao Chenhui
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

2012-07-02 Thread Zhao Chenhui
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

2012-07-02 Thread Zhao Chenhui
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

2012-07-03 Thread Zhao Chenhui
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

2012-07-03 Thread Zhao Chenhui
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

2012-07-03 Thread Zhao Chenhui
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

2012-07-03 Thread Zhao Chenhui
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

2012-07-05 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-20 Thread Zhao Chenhui
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

2012-07-23 Thread Zhao Chenhui
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

2012-08-02 Thread Zhao Chenhui
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

2012-08-02 Thread Zhao Chenhui
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

2012-08-07 Thread Zhao Chenhui
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

2012-08-07 Thread Zhao Chenhui
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

2012-08-07 Thread Zhao Chenhui
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

2012-08-07 Thread Zhao Chenhui
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

2012-08-07 Thread Zhao Chenhui
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

2012-08-08 Thread Zhao Chenhui
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

2012-08-10 Thread Zhao Chenhui
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

2012-08-10 Thread Zhao Chenhui
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

2012-08-14 Thread Zhao Chenhui
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

2012-08-14 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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()

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-03 Thread Zhao Chenhui
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

2013-04-06 Thread Zhao Chenhui
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

2013-04-14 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-19 Thread Zhao Chenhui
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

2013-04-22 Thread Zhao Chenhui
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

2013-04-22 Thread Zhao Chenhui
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

2013-04-23 Thread Zhao Chenhui
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

2013-04-24 Thread Zhao Chenhui
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

2013-04-24 Thread Zhao Chenhui
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

2013-04-24 Thread Zhao Chenhui
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

2013-04-24 Thread Zhao Chenhui
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

2013-04-28 Thread Zhao Chenhui
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

2013-04-28 Thread Zhao Chenhui
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

2013-05-28 Thread Zhao Chenhui
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

2013-05-28 Thread Zhao Chenhui
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

2013-06-13 Thread Zhao Chenhui
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

2013-02-07 Thread Zhao Chenhui
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


  1   2   >