[PATCH] cpuidle: remove cpu_pm calls when entering a idle state

2016-10-21 Thread Chenhui Zhao
The functions, cpu_pm_enter and cpu_pm_exit, assume that CPU would
be reset when entering and exiting a idle state. If that is not the
case, they would cause issue.

Signed-off-by: Chenhui Zhao 
---
 include/linux/cpuidle.h | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index bb31373..063af89 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -261,12 +261,7 @@ static inline int cpuidle_register_governor(struct 
cpuidle_governor *gov)
return idx; \
}   \
\
-   __ret = cpu_pm_enter(); \
-   if (!__ret) {   \
-   __ret = low_level_idle_enter(idx);  \
-   cpu_pm_exit();  \
-   }   \
-   \
+   __ret = low_level_idle_enter(idx);  \
__ret ? -1 : idx;   \
 })
 
-- 
1.9.1



Re: [PATCH 2/2] soc: nxp: Add a RCPM driver

2016-08-02 Thread Chenhui Zhao
On Mon, Aug 1, 2016 at 8:25 PM, Arnd Bergmann  wrote:
> On Monday, August 1, 2016 5:49:03 PM CEST Chenhui Zhao wrote:
>> The NXP's QorIQ Processors based on ARM Core have a RCPM module
>> (Run Control and Power Management), which performs all device-level
>> tasks associated with power management.
>>
>> This patch mainly implements the wakeup sources configuration before
>> entering LPM20, a low power state of device-level. The devices can be
>> waked up by specified sources, such as Flextimer, GPIO and so on.
>>
>> Signed-off-by: Chenhui Zhao 
>
> Adding irqchip maintainers to cc, as this wakeup handling is normally
> part of the irq controller.
>
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +/* So far there are not more than two registers */
>> +#define RCPM_IPPDEXPCR0  0x140
>> +#define RCPM_IPPDEXPCR1  0x144
>> +#define RCPM_IPPDEXPCR(x)(RCPM_IPPDEXPCR0 + 4 * x)
>> +#define RCPM_WAKEUP_CELL_MAX_SIZE2
>> +
>> +/* it reprents the number of the registers RCPM_IPPDEXPCR */
>> +static unsigned int rcpm_wakeup_cells;
>> +static void __iomem *rcpm_reg_base;
>> +static u32 ippdexpcr[RCPM_WAKEUP_CELL_MAX_SIZE];
>
> Can you make these local to the context of whoever
> calls into the driver?
>
>
>> +static void rcpm_wakeup_fixup(struct device *dev, void *data)
>> +{
>> + struct device_node *node = dev ? dev->of_node : NULL;
>> + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1];
>> + int ret;
>> + int i;
>> +
>> + if (!dev || !node || !device_may_wakeup(dev))
>> + return;
>> +
>> + /*
>> +  * Get the values in the "rcpm-wakeup" property.
>> +  * Refer to Documentation/devicetree/bindings/soc/fsl/rcpm.txt
>> +  */
>> + ret = of_property_read_u32_array(node, "rcpm-wakeup",c
>> +  value, rcpm_wakeup_cells + 1);
>
> My first impression is that you are trying to do something
> in a platform specific way that should be handled by common
> code here.
>
> You are parsing rcpm_wakeup_cells once for the global node,
> but you don't check whether the device that has the rcpm-wakeup
> node actually refers to this instance, and that would require
> an incompatible change if we ever get an implementation that
> has multiple such nodes.
>
> Arnd

The code is specific to the QorIQ platform.

For a given QorIQ SoC, the value of the "fsl,#rcpm-wakeup-cells"
property would not change. Anyway, your suggestion is better getting
the rcpm node from the "rcpm-wakeup" property.

Thanks,
Chenhui


Re: [PATCH 2/2] soc: nxp: Add a RCPM driver

2016-08-02 Thread Chenhui Zhao
On Mon, Aug 1, 2016 at 9:22 PM, Marc Zyngier  wrote:
>
> On 01/08/16 10:49, Chenhui Zhao wrote:
> > The NXP's QorIQ Processors based on ARM Core have a RCPM module
> > (Run Control and Power Management), which performs all device-level
> > tasks associated with power management.
> >
> > This patch mainly implements the wakeup sources configuration before
> > entering LPM20, a low power state of device-level. The devices can be
> > waked up by specified sources, such as Flextimer, GPIO and so on.
> >
> > Signed-off-by: Chenhui Zhao 
> > ---
> >  drivers/soc/fsl/Makefile |   1 +
> >  drivers/soc/fsl/pm/Makefile  |   1 +
> >  drivers/soc/fsl/pm/ls-rcpm.c | 144 
> > +++
> >  3 files changed, 146 insertions(+)
> >  create mode 100644 drivers/soc/fsl/pm/Makefile
> >  create mode 100644 drivers/soc/fsl/pm/ls-rcpm.c
> >
> > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
> > index 203307f..b5adbaf 100644
> > --- a/drivers/soc/fsl/Makefile
> > +++ b/drivers/soc/fsl/Makefile
> > @@ -4,3 +4,4 @@
> >
> >  obj-$(CONFIG_QUICC_ENGINE)   += qe/
> >  obj-$(CONFIG_CPM)+= qe/
> > +obj-$(CONFIG_SUSPEND)+= pm/
> > diff --git a/drivers/soc/fsl/pm/Makefile b/drivers/soc/fsl/pm/Makefile
> > new file mode 100644
> > index 000..e275d63
> > --- /dev/null
> > +++ b/drivers/soc/fsl/pm/Makefile
> > @@ -0,0 +1 @@
> > +obj-$(CONFIG_ARCH_LAYERSCAPE) += ls-rcpm.o
> > diff --git a/drivers/soc/fsl/pm/ls-rcpm.c b/drivers/soc/fsl/pm/ls-rcpm.c
> > new file mode 100644
> > index 000..c5f2b97
> > --- /dev/null
> > +++ b/drivers/soc/fsl/pm/ls-rcpm.c
> > @@ -0,0 +1,144 @@
> > +/*
> > + * Run Control and Power Management (RCPM) driver
> > + *
> > + * Copyright 2016 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.
> > + *
> > + * 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.
> > + *
> > + */
> > +#define pr_fmt(fmt) "RCPM: %s: " fmt, __func__
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +/* So far there are not more than two registers */
> > +#define RCPM_IPPDEXPCR0  0x140
> > +#define RCPM_IPPDEXPCR1  0x144
> > +#define RCPM_IPPDEXPCR(x)(RCPM_IPPDEXPCR0 + 4 * x)
> > +#define RCPM_WAKEUP_CELL_MAX_SIZE2
> > +
> > +/* it reprents the number of the registers RCPM_IPPDEXPCR */
> > +static unsigned int rcpm_wakeup_cells;
> > +static void __iomem *rcpm_reg_base;
> > +static u32 ippdexpcr[RCPM_WAKEUP_CELL_MAX_SIZE];
> > +
> > +static inline void rcpm_reg_write(u32 offset, u32 value)
> > +{
> > + iowrite32be(value, rcpm_reg_base + offset);
> > +}
> > +
> > +static inline u32 rcpm_reg_read(u32 offset)
> > +{
> > + return ioread32be(rcpm_reg_base + offset);
> > +}
> > +
> > +static void rcpm_wakeup_fixup(struct device *dev, void *data)
> > +{
> > + struct device_node *node = dev ? dev->of_node : NULL;
> > + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1];
> > + int ret;
> > + int i;
> > +
> > + if (!dev || !node || !device_may_wakeup(dev))
> > + return;
> > +
> > + /*
> > +  * Get the values in the "rcpm-wakeup" property.
> > +  * Refer to Documentation/devicetree/bindings/soc/fsl/rcpm.txt
> > +  */
> > + ret = of_property_read_u32_array(node, "rcpm-wakeup",
> > +  value, rcpm_wakeup_cells + 1);
> > + if (ret)
> > + return;
> > +
> > + pr_debug("wakeup source: the device %s\n", node->full_name);
>
> This looks absolutely dreadful. You are parsing every node for each
> device, and apply a set-in-stone configuration.
>
> The normal way to handle this is by making this device an interrupt
> controller, and honour the irq_set_wake API. This has already been done
> on other FSL/NXP hardware (see the iMX GPC stuff).
>
> Thanks,
>
> M.

The RCPM IP block is really not an interrupt controller, instead it is
related to power management. The code in this patch is to set the bits
in the IPPDEXPCR register. Setting these bits can make the
corresponding IP block alive during the period of sleep, so that the
IP blocks working as wakeup sources can wake the device. The
"rcpm-wakeup" property records the bit mask which should be set when
the IP block is working as wakeup source. The bit definition may be
different for each QorIQ SoC. The operation is specific to QorIQ
platform, so put the code in drivers/soc/fsl/pm/.

Thanks,
Chenhui


[PATCH v3 0/5] powerpc/pm: QorIQ deep sleep

2016-08-02 Thread Chenhui Zhao
Changes for v3:
* add mcke-gpios in dts to specify the GPIO pin which works as MCKE signal

Changes for v2:
* Ioremap every dts node used in the patches.
* Check the board compatible string to see if the board supports deep sleep.
* Can not reserve the first page of DDR memory, because PPC64 doesn't support
  changing the kernel base address. So still save and restore the first 128 
bytes
  of DDR memory.
* Still save and restoer CCSR registers in kernel, because bootloader doesn't
  know what register values to restore
* Changed copyright and email address from freescale to NXP

Please refer to the version 1:
[1/4] powerpc/85xx: support sleep feature on QorIQ SoCs with RCPM
http://patchwork.ozlabs.org/patch/502549/

[2/4] powerpc: get the physical base address of DCSR
http://patchwork.ozlabs.org/patch/502551/
It is removed.

[3/4] powerpc: pm: add EPU FSM configuration for deep sleep
http://patchwork.ozlabs.org/patch/502548/

[4/4] powerpc: pm: support deep sleep feature on T104x
http://patchwork.ozlabs.org/patch/502550/


Chenhui Zhao (5):
  powerpc/dts: add mcke-gpios for PM feature
  powerpc/85xx: support sleep feature on QorIQ SoCs with RCPM
  powerpc: pm: add EPU FSM configuration for deep sleep
  powerpc/pm: support deep sleep feature on T104x
  powerpc/pm: save and restore registers during deep sleep

 Documentation/devicetree/bindings/soc/fsl/rcpm.txt |  13 +
 arch/powerpc/Kconfig   |   3 +-
 arch/powerpc/boot/dts/fsl/t1040si-post.dtsi|   3 +
 arch/powerpc/include/asm/fsl_pm.h  |  28 +-
 arch/powerpc/kernel/asm-offsets.c  |  12 +
 arch/powerpc/kernel/fsl_booke_entry_mapping.S  |  10 +
 arch/powerpc/kernel/head_64.S  |   2 +-
 arch/powerpc/platforms/85xx/Kconfig|   5 +
 arch/powerpc/platforms/85xx/Makefile   |   2 +
 arch/powerpc/platforms/85xx/deepsleep.c| 384 +++
 arch/powerpc/platforms/85xx/qoriq_pm.c |  84 
 arch/powerpc/platforms/85xx/sleep_fsm.c| 267 +++
 arch/powerpc/platforms/85xx/sleep_fsm.h|  92 
 arch/powerpc/platforms/85xx/t104x_deepsleep.S  | 531 +
 arch/powerpc/platforms/86xx/Kconfig|   1 +
 arch/powerpc/sysdev/fsl_rcpm.c |  28 +-
 16 files changed, 1446 insertions(+), 19 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/deepsleep.c
 create mode 100644 arch/powerpc/platforms/85xx/qoriq_pm.c
 create mode 100644 arch/powerpc/platforms/85xx/sleep_fsm.c
 create mode 100644 arch/powerpc/platforms/85xx/sleep_fsm.h
 create mode 100644 arch/powerpc/platforms/85xx/t104x_deepsleep.S

-- 
1.9.1



[PATCH v3 1/5] powerpc/dts: add mcke-gpios for PM feature

2016-08-02 Thread Chenhui Zhao
Signed-off-by: Chenhui Zhao 
---
 Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 13 +
 arch/powerpc/boot/dts/fsl/t1040si-post.dtsi|  3 +++
 2 files changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt 
b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
index e284e4e..1d44a80 100644
--- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
+++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
@@ -21,6 +21,10 @@ Required properites:
* "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm
* "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm
 
+Optional properites:
+  - mcke-gpios : The GPIO pin is used for keeping the MCKE signal of DDR 
modules
+low in the LPM35 state on some platforms, such as T1040.
+
 All references to "1.0" and "2.0" refer to the QorIQ chassis version to
 which the chip complies.
 Chassis VersionExample Chips
@@ -37,6 +41,15 @@ The RCPM node for T4240:
fsl,#rcpm-wakeup-cells = <2>;
};
 
+The RCPM node for T1040 (which supports LPM35 state):
+   rcpm: global-utilities@e2000 {
+   compatible = "fsl,t1040-rcpm", "fsl,qoriq-rcpm-2.1";
+   reg = <0xe2000 0x1000>;
+   fsl,#rcpm-wakeup-cells = <1>;
+   mcke-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>
+   };
+
+
 * Freescale RCPM Wakeup Source Device Tree Bindings
 ---
 Required fsl,rcpm-wakeup property should be added to a device node if the 
device
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi 
b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index 507649e..f66e7dd 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -33,6 +33,7 @@
  */
 
 #include 
+#include 
 
 &bman_fbpr {
compatible = "fsl,bman-fbpr";
@@ -474,6 +475,8 @@
rcpm: global-utilities@e2000 {
compatible = "fsl,t1040-rcpm", "fsl,qoriq-rcpm-2.1";
reg = <0xe2000 0x1000>;
+   fsl,#rcpm-wakeup-cells = <1>;
+   mcke-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
 
sfp: sfp@e8000 {
-- 
1.9.1



[PATCH v3 3/5] powerpc: pm: add EPU FSM configuration for deep sleep

2016-08-02 Thread Chenhui Zhao
In the last stage of deep sleep, software will trigger a Finite
State Machine (FSM) to control the hardware precedure, such as
board isolation, killing PLLs, removing power, and so on.

When the system is waked up by an interrupt, the FSM controls the
hardware to complete the early resume precedure.

This patch configure the EPU FSM preparing for deep sleep.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/platforms/85xx/Makefile|   2 +-
 arch/powerpc/platforms/85xx/sleep_fsm.c | 267 
 arch/powerpc/platforms/85xx/sleep_fsm.h |  92 +++
 3 files changed, 360 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/platforms/85xx/sleep_fsm.c
 create mode 100644 arch/powerpc/platforms/85xx/sleep_fsm.h

diff --git a/arch/powerpc/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index fdae28b..87fb847 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -3,7 +3,7 @@
 #
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_FSL_PMC)+= mpc85xx_pm_ops.o
-obj-$(CONFIG_FSL_QORIQ_PM)   += qoriq_pm.o
+obj-$(CONFIG_FSL_QORIQ_PM)   += qoriq_pm.o sleep_fsm.o
 
 obj-y += common.o
 
diff --git a/arch/powerpc/platforms/85xx/sleep_fsm.c 
b/arch/powerpc/platforms/85xx/sleep_fsm.c
new file mode 100644
index 000..2b0c16b
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/sleep_fsm.c
@@ -0,0 +1,267 @@
+/*
+ * Freescale deep sleep FSM (finite-state machine) configuration
+ *
+ * Copyright 2016 Freescale Semiconductor Inc.
+ *
+ * Author: Hongbo Zhang 
+ * Chenhui Zhao 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#include "sleep_fsm.h"
+
+struct fsm_reg_vals {
+   u32 offset;
+   u32 value;
+};
+
+/*
+ * These values are from chip's reference manual. For example,
+ * the values for T1040 can be found in "8.4.3.8 Programming
+ * supporting deep sleep mode" of Chapter 8 "Run Control and
+ * Power Management (RCPM)".
+ * The default value is applied to T1040, T1042, T1024.
+ */
+struct fsm_reg_vals epu_default_val[] = {
+   /* EPGCR (Event Processor Global Control Register) */
+   {EPGCR, 0},
+   /* EPECR (Event Processor Event Control Registers) */
+   {EPECR0 + EPECR_STRIDE * 0, 0},
+   {EPECR0 + EPECR_STRIDE * 1, 0},
+   {EPECR0 + EPECR_STRIDE * 2, 0xF0004004},
+   {EPECR0 + EPECR_STRIDE * 3, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 4, 0x2084},
+   {EPECR0 + EPECR_STRIDE * 5, 0x0804},
+   {EPECR0 + EPECR_STRIDE * 6, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 7, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 8, 0x6084},
+   {EPECR0 + EPECR_STRIDE * 9, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 10, 0x4284},
+   {EPECR0 + EPECR_STRIDE * 11, 0x9084},
+   {EPECR0 + EPECR_STRIDE * 12, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 13, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 14, 0x0284},
+   {EPECR0 + EPECR_STRIDE * 15, 0x0004},
+   /*
+* EPEVTCR (Event Processor EVT Pin Control Registers)
+* SCU8 triger EVT2, and SCU11 triger EVT9
+*/
+   {EPEVTCR0 + EPEVTCR_STRIDE * 0, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 1, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 2, 0x8001},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 3, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 4, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 5, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 6, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 7, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 8, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 9, 0xB001},
+   /* EPCMPR (Event Processor Counter Compare Registers) */
+   {EPCMPR0 + EPCMPR_STRIDE * 0, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 1, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 2, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 3, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 4, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 5, 0x0020},
+   {EPCMPR0 + EPCMPR_STRIDE * 6, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 7, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 8, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 9, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 10, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 11, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 12, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 13, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 14, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 15, 0x00FF},
+   /* EPCCR (Event Processor Counter Control Registers) */
+   {EPCCR0 + EPCCR_STRIDE * 0, 0},
+   {EPCCR0 + EPCCR_STRIDE * 1, 0},
+   {EPCCR0 + EPCCR_STRIDE * 2, 0x9284},
+   {EPCCR0 + EPCCR_STRIDE * 3, 0},
+   {EPCCR0 + EPCCR_STRIDE * 4, 0x9284},
+   {EP

[PATCH v3 2/5] powerpc/85xx: support sleep feature on QorIQ SoCs with RCPM

2016-08-02 Thread Chenhui Zhao
In sleep mode, the clocks of e500 cores and unused IP blocks is
turned off. The IP blocks which are allowed to wake up the processor
are still running.

The sleep mode is equal to the Standby state in Linux. Use the
command to enter sleep mode:
  echo standby > /sys/power/state

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/Kconfig   |  3 +-
 arch/powerpc/include/asm/fsl_pm.h  |  2 +-
 arch/powerpc/platforms/85xx/Kconfig|  5 +++
 arch/powerpc/platforms/85xx/Makefile   |  1 +
 arch/powerpc/platforms/85xx/qoriq_pm.c | 59 ++
 arch/powerpc/platforms/86xx/Kconfig|  1 +
 arch/powerpc/sysdev/fsl_rcpm.c | 20 
 7 files changed, 74 insertions(+), 17 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/qoriq_pm.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 0a9d439..078d08c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -242,7 +242,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
@@ -778,7 +778,6 @@ config FSL_PCI
 
 config FSL_PMC
bool
-   default y
depends on SUSPEND && (PPC_85xx || PPC_86xx)
help
  Freescale MPC85xx/MPC86xx power management controller support
diff --git a/arch/powerpc/include/asm/fsl_pm.h 
b/arch/powerpc/include/asm/fsl_pm.h
index 47df55e..e05049b 100644
--- a/arch/powerpc/include/asm/fsl_pm.h
+++ b/arch/powerpc/include/asm/fsl_pm.h
@@ -34,7 +34,7 @@ struct fsl_pm_ops {
void (*cpu_exit_state)(int cpu, int state);
void (*cpu_up_prepare)(int cpu);
void (*cpu_die)(int cpu);
-   int (*plat_enter_sleep)(void);
+   int (*plat_enter_sleep)(int state);
void (*freeze_time_base)(bool freeze);
 
/* keep the power of IP blocks during sleep/deep sleep */
diff --git a/arch/powerpc/platforms/85xx/Kconfig 
b/arch/powerpc/platforms/85xx/Kconfig
index e626461..dff2ea6 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -9,6 +9,8 @@ menuconfig FSL_SOC_BOOKE
select SERIAL_8250_EXTENDED if SERIAL_8250
select SERIAL_8250_SHARE_IRQ if SERIAL_8250
select FSL_CORENET_RCPM if PPC_E500MC
+   select FSL_QORIQ_PM if SUSPEND && PPC_E500MC
+   select FSL_PMC if SUSPEND && !PPC_E500MC
default y
 
 if FSL_SOC_BOOKE
@@ -289,3 +291,6 @@ endif # FSL_SOC_BOOKE
 
 config TQM85xx
bool
+
+config FSL_QORIQ_PM
+   bool
diff --git a/arch/powerpc/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index 7bc86da..fdae28b 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)+= mpc85xx_pm_ops.o
+obj-$(CONFIG_FSL_QORIQ_PM)   += qoriq_pm.o
 
 obj-y += common.o
 
diff --git a/arch/powerpc/platforms/85xx/qoriq_pm.c 
b/arch/powerpc/platforms/85xx/qoriq_pm.c
new file mode 100644
index 000..c97ef8f
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/qoriq_pm.c
@@ -0,0 +1,59 @@
+/*
+ * Support Power Management feature
+ *
+ * Copyright 2016 Freescale Semiconductor Inc.
+ *
+ * Author: Chenhui Zhao 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+static unsigned int pm_modes;
+
+static int qoriq_suspend_enter(suspend_state_t state)
+{
+   int ret = 0;
+
+   switch (state) {
+   case PM_SUSPEND_STANDBY:
+   ret = qoriq_pm_ops->plat_enter_sleep(FSL_PM_SLEEP);
+   break;
+   default:
+   ret = -EINVAL;
+   }
+
+   return ret;
+}
+
+static int qoriq_suspend_valid(suspend_state_t state)
+{
+
+   if (state == PM_SUSPEND_STANDBY && (pm_modes & FSL_PM_SLEEP))
+   return 1;
+
+   return 0;
+}
+
+static const struct platform_suspend_ops qoriq_suspend_ops = {
+   .valid = qoriq_suspend_valid,
+   .enter = qoriq_suspend_enter,
+};
+
+static int __init qoriq_suspend_init(void)
+{
+   /* support sleep by default */
+   pm_modes |= FSL_PM_SLEEP;
+
+   suspend_set_ops(&qoriq_suspend_ops);
+   return 0;
+}
+arch_initcall(qoriq_suspend_init);
diff --git a/arch/powerpc/platforms/86xx/Kconfig 
b/arch/powerpc/platforms/86xx/Kconfig
index 1afd1e4..09638e0 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -5,6 +5,7 @@ menuconfig PPC_86xx
select FSL_SOC
se

[PATCH v3 5/5] powerpc/pm: save and restore registers during deep sleep

2016-08-02 Thread Chenhui Zhao
Some CCSR registers will lost during deep sleep. Therefore,
should save them before entering deep sleep, and restore them
when resuming from deep sleep.

Signed-off-by: Tang Yuantian 
Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/include/asm/fsl_pm.h   |   2 +
 arch/powerpc/platforms/85xx/deepsleep.c | 108 +++-
 2 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/fsl_pm.h 
b/arch/powerpc/include/asm/fsl_pm.h
index 48c2631..95601fb 100644
--- a/arch/powerpc/include/asm/fsl_pm.h
+++ b/arch/powerpc/include/asm/fsl_pm.h
@@ -61,7 +61,9 @@ extern void fsl_dp_enter_low(void *priv);
 extern void fsl_booke_deep_sleep_resume(void);
 
 struct fsl_iomap {
+   void *ccsr_lcc_base;
void *ccsr_scfg_base;
+   void *ccsr_dcfg_base;
void *ccsr_rcpm_base;
void *ccsr_ddr_base;
void *ccsr_gpio1_base;
diff --git a/arch/powerpc/platforms/85xx/deepsleep.c 
b/arch/powerpc/platforms/85xx/deepsleep.c
index 9521d99..71987fd 100644
--- a/arch/powerpc/platforms/85xx/deepsleep.c
+++ b/arch/powerpc/platforms/85xx/deepsleep.c
@@ -23,6 +23,8 @@
 
 #include "sleep_fsm.h"
 
+#define CCSR_LAW_OFFSET0xC00
+
 #define CPC_CPCHDBCR0  0x0f00
 #define CPC_CPCHDBCR0_SPEC_DIS 0x0800
 
@@ -41,6 +43,17 @@
 #define QORIQ_CPLD_MISCCSR 0x17
 #define QORIQ_CPLD_MISCCSR_SLEEPEN 0x40
 
+#define CCSR_LCC_BSTRH 0x20
+#define CCSR_LCC_BSTRL 0x24
+#define CCSR_LCC_BSTAR 0x28
+
+#define CCSR_DCFG_BRR  0xE4
+
+#define CCSR_RCPM_PCTBENR  0x1A0
+
+/* the target id for the memory complex 1 (MC1) */
+#define MC1_TRGT_ID0x10
+
 /* 128 bytes buffer for restoring data broke by DDR training initialization */
 #define DDR_BUF_SIZE   128
 static u8 ddr_buff[DDR_BUF_SIZE] __aligned(64);
@@ -50,6 +63,23 @@ static void fsl_dp_iounmap(void);
 
 static struct fsl_iomap fsl_dp_priv;
 
+struct fsl_ccsr_law {
+   u32 lawbarh;/* LAWn base address high */
+   u32 lawbarl;/* LAWn base address low */
+   u32 lawar;  /* LAWn attributes */
+   u32 reserved;
+};
+
+static struct fsl_regs_buffer {
+   u32 bstrh;
+   u32 bstrl;
+   u32 bstar;
+   u32 brr;
+   u32 pctbenr;
+   u32 law_count;
+   void *law_regs;
+} fsl_dp_buffer;
+
 static const struct of_device_id fsl_dp_cpld_ids[] __initconst = {
{ .compatible = "fsl,t1024-cpld", },
{ .compatible = "fsl,t1040rdb-cpld", },
@@ -65,6 +95,60 @@ static const struct of_device_id fsl_dp_fpga_ids[] 
__initconst = {
{}
 };
 
+static void fsl_regs_save(struct fsl_iomap *base,
+ struct fsl_regs_buffer *buffer)
+{
+   int i;
+   struct fsl_ccsr_law *src = base->ccsr_lcc_base + CCSR_LAW_OFFSET;
+   struct fsl_ccsr_law *dst = buffer->law_regs;
+
+   buffer->bstrh = in_be32(base->ccsr_lcc_base + CCSR_LCC_BSTRH);
+   buffer->bstrl = in_be32(base->ccsr_lcc_base + CCSR_LCC_BSTRL);
+   buffer->bstar = in_be32(base->ccsr_lcc_base + CCSR_LCC_BSTAR);
+   buffer->brr = in_be32(base->ccsr_dcfg_base + CCSR_DCFG_BRR);
+   buffer->pctbenr = in_be32(base->ccsr_rcpm_base + CCSR_RCPM_PCTBENR);
+
+   for (i = 0; i < buffer->law_count; i++) {
+   dst->lawbarh = in_be32(&src->lawbarh);
+   dst->lawbarl = in_be32(&src->lawbarl);
+   dst->lawar = in_be32(&src->lawar);
+   dst++;
+   src++;
+   }
+}
+
+static void fsl_regs_restore(struct fsl_iomap *base,
+struct fsl_regs_buffer *buffer)
+{
+   int i;
+   u32 attr;
+   struct fsl_ccsr_law *src = buffer->law_regs;
+   struct fsl_ccsr_law *dst = base->ccsr_lcc_base + CCSR_LAW_OFFSET;
+
+   out_be32(base->ccsr_lcc_base + CCSR_LCC_BSTRH, buffer->bstrh);
+   out_be32(base->ccsr_lcc_base + CCSR_LCC_BSTRL, buffer->bstrl);
+   out_be32(base->ccsr_lcc_base + CCSR_LCC_BSTAR, buffer->bstar);
+   out_be32(base->ccsr_dcfg_base + CCSR_DCFG_BRR, buffer->brr);
+   out_be32(base->ccsr_rcpm_base + CCSR_RCPM_PCTBENR, buffer->pctbenr);
+
+   for (i = 0; i < buffer->law_count; i++) {
+   /*
+* If the LAW with the target id of MC1 has been set,
+* skip. Because changing it here causes memory
+* access error.
+*/
+   attr = in_be32(&dst->lawar);
+   if (((attr >> 20) & 0xff) == MC1_TRGT_ID)
+   continue;
+   out_be32(&dst->lawar, 0);
+   out_be32(&dst->lawbarl, src->lawbarl);
+   out_be32(&dst->lawbarh, src->lawbarh);
+   out_be32(&dst->lawar, src->lawar);
+   src++;
+   dst++;
+   }
+}
+

[PATCH v3 1/5] powerpc/dts: add mcke-gpios for PM feature

2016-08-02 Thread Chenhui Zhao
Signed-off-by: Chenhui Zhao 
---
 Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 13 +
 arch/powerpc/boot/dts/fsl/t1040si-post.dtsi|  3 +++
 2 files changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt 
b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
index e284e4e..1d44a80 100644
--- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
+++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
@@ -21,6 +21,10 @@ Required properites:
* "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm
* "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm
 
+Optional properites:
+  - mcke-gpios : The GPIO pin is used for keeping the MCKE signal of DDR 
modules
+low in the LPM35 state on some platforms, such as T1040.
+
 All references to "1.0" and "2.0" refer to the QorIQ chassis version to
 which the chip complies.
 Chassis VersionExample Chips
@@ -37,6 +41,15 @@ The RCPM node for T4240:
fsl,#rcpm-wakeup-cells = <2>;
};
 
+The RCPM node for T1040 (which supports LPM35 state):
+   rcpm: global-utilities@e2000 {
+   compatible = "fsl,t1040-rcpm", "fsl,qoriq-rcpm-2.1";
+   reg = <0xe2000 0x1000>;
+   fsl,#rcpm-wakeup-cells = <1>;
+   mcke-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>
+   };
+
+
 * Freescale RCPM Wakeup Source Device Tree Bindings
 ---
 Required fsl,rcpm-wakeup property should be added to a device node if the 
device
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi 
b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index 507649e..f66e7dd 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -33,6 +33,7 @@
  */
 
 #include 
+#include 
 
 &bman_fbpr {
compatible = "fsl,bman-fbpr";
@@ -474,6 +475,8 @@
rcpm: global-utilities@e2000 {
compatible = "fsl,t1040-rcpm", "fsl,qoriq-rcpm-2.1";
reg = <0xe2000 0x1000>;
+   fsl,#rcpm-wakeup-cells = <1>;
+   mcke-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
 
sfp: sfp@e8000 {
-- 
1.9.1



[PATCH v3 4/5] powerpc/pm: support deep sleep feature on T104x

2016-08-02 Thread Chenhui Zhao
T104x has deep sleep feature, which can switch off most parts of
the SoC when it is in deep sleep mode. This way, it becomes more
energy-efficient.

The DDR controller will also be powered off in deep sleep. Therefore,
the last stage (the latter part of fsl_dp_enter_low) will run without DDR
access. This piece of code and related TLBs are prefetched in advance.

Due to the different initialization code between 32-bit and 64-bit, they
have separate resume entry and precedure.

The feature supports 32-bit and 64-bit kernel mode.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/include/asm/fsl_pm.h |  24 ++
 arch/powerpc/kernel/asm-offsets.c |  12 +
 arch/powerpc/kernel/fsl_booke_entry_mapping.S |  10 +
 arch/powerpc/kernel/head_64.S |   2 +-
 arch/powerpc/platforms/85xx/Makefile  |   1 +
 arch/powerpc/platforms/85xx/deepsleep.c   | 278 ++
 arch/powerpc/platforms/85xx/qoriq_pm.c|  25 ++
 arch/powerpc/platforms/85xx/t104x_deepsleep.S | 531 ++
 arch/powerpc/sysdev/fsl_rcpm.c|   8 +-
 9 files changed, 889 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/deepsleep.c
 create mode 100644 arch/powerpc/platforms/85xx/t104x_deepsleep.S

diff --git a/arch/powerpc/include/asm/fsl_pm.h 
b/arch/powerpc/include/asm/fsl_pm.h
index e05049b..48c2631 100644
--- a/arch/powerpc/include/asm/fsl_pm.h
+++ b/arch/powerpc/include/asm/fsl_pm.h
@@ -20,6 +20,7 @@
 
 #define PLAT_PM_SLEEP  20
 #define PLAT_PM_LPM20  30
+#define PLAT_PM_LPM35  40
 
 #define FSL_PM_SLEEP   (1 << 0)
 #define FSL_PM_DEEP_SLEEP  (1 << 1)
@@ -48,4 +49,27 @@ extern const struct fsl_pm_ops *qoriq_pm_ops;
 
 int __init fsl_rcpm_init(void);
 
+#ifdef CONFIG_FSL_QORIQ_PM
+int fsl_enter_deepsleep(void);
+int fsl_deepsleep_init(void);
+#else
+static inline int fsl_enter_deepsleep(void) { return -1; }
+static inline int fsl_deepsleep_init(void) { return -1; }
+#endif
+
+extern void fsl_dp_enter_low(void *priv);
+extern void fsl_booke_deep_sleep_resume(void);
+
+struct fsl_iomap {
+   void *ccsr_scfg_base;
+   void *ccsr_rcpm_base;
+   void *ccsr_ddr_base;
+   void *ccsr_gpio1_base;
+   void *ccsr_cpc_base;
+   void *dcsr_epu_base;
+   void *dcsr_npc_base;
+   void *dcsr_rcpm_base;
+   void *cpld_base;
+   void *fpga_base;
+};
 #endif /* __PPC_FSL_PM_H */
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 9ea0955..cc488f9 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -68,6 +68,10 @@
 #include "../mm/mmu_decl.h"
 #endif
 
+#ifdef CONFIG_FSL_QORIQ_PM
+#include 
+#endif
+
 int main(void)
 {
DEFINE(THREAD, offsetof(struct task_struct, thread));
@@ -783,5 +787,13 @@ int main(void)
 
DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER);
 
+#ifdef CONFIG_FSL_QORIQ_PM
+   DEFINE(CCSR_CPC_BASE, offsetof(struct fsl_iomap, ccsr_cpc_base));
+   DEFINE(CCSR_GPIO1_BASE, offsetof(struct fsl_iomap, ccsr_gpio1_base));
+   DEFINE(CCSR_RCPM_BASE, offsetof(struct fsl_iomap, ccsr_rcpm_base));
+   DEFINE(CCSR_DDR_BASE, offsetof(struct fsl_iomap, ccsr_ddr_base));
+   DEFINE(CCSR_SCFG_BASE, offsetof(struct fsl_iomap, ccsr_scfg_base));
+   DEFINE(DCSR_EPU_BASE, offsetof(struct fsl_iomap, dcsr_epu_base));
+#endif
return 0;
 }
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S 
b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
index 83dd0f6..659b059 100644
--- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S
+++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
@@ -173,6 +173,10 @@ skpinv:addir6,r6,1 /* 
Increment */
lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@h
ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@l
mtspr   SPRN_MAS2,r6
+#ifdef ENTRY_DEEPSLEEP_SETUP
+   LOAD_REG_IMMEDIATE(r8, MEMORY_START)
+   ori r8,r8,(MAS3_SX|MAS3_SW|MAS3_SR)
+#endif
mtspr   SPRN_MAS3,r8
tlbwe
 
@@ -215,12 +219,18 @@ next_tlb_setup:
#error You need to specify the mapping or not use this at all.
 #endif
 
+#ifdef ENTRY_DEEPSLEEP_SETUP
+   LOAD_REG_ADDR(r6, 2f)
+   mfmsr   r7
+   rlwinm  r7,r7,0,~(MSR_IS|MSR_DS)
+#else
lis r7,MSR_KERNEL@h
ori r7,r7,MSR_KERNEL@l
bl  1f  /* Find our address */
 1: mflrr9
rlwimi  r6,r9,0,20,31
addir6,r6,(2f - 1b)
+#endif
mtspr   SPRN_SRR0,r6
mtspr   SPRN_SRR1,r7
rfi /* start execution out of TLB1[0] entry 
*/
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 2d14774..21fa124 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -829,7 +829,7 @@ _GLOBAL(start_secondary_resume)
 /*
  * This subroutine clobbers r11 and r12

[PATCH 2/2] soc: nxp: Add a RCPM driver

2016-08-01 Thread Chenhui Zhao
The NXP's QorIQ Processors based on ARM Core have a RCPM module
(Run Control and Power Management), which performs all device-level
tasks associated with power management.

This patch mainly implements the wakeup sources configuration before
entering LPM20, a low power state of device-level. The devices can be
waked up by specified sources, such as Flextimer, GPIO and so on.

Signed-off-by: Chenhui Zhao 
---
 drivers/soc/fsl/Makefile |   1 +
 drivers/soc/fsl/pm/Makefile  |   1 +
 drivers/soc/fsl/pm/ls-rcpm.c | 144 +++
 3 files changed, 146 insertions(+)
 create mode 100644 drivers/soc/fsl/pm/Makefile
 create mode 100644 drivers/soc/fsl/pm/ls-rcpm.c

diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 203307f..b5adbaf 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_QUICC_ENGINE) += qe/
 obj-$(CONFIG_CPM)  += qe/
+obj-$(CONFIG_SUSPEND)  += pm/
diff --git a/drivers/soc/fsl/pm/Makefile b/drivers/soc/fsl/pm/Makefile
new file mode 100644
index 000..e275d63
--- /dev/null
+++ b/drivers/soc/fsl/pm/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_LAYERSCAPE) += ls-rcpm.o
diff --git a/drivers/soc/fsl/pm/ls-rcpm.c b/drivers/soc/fsl/pm/ls-rcpm.c
new file mode 100644
index 000..c5f2b97
--- /dev/null
+++ b/drivers/soc/fsl/pm/ls-rcpm.c
@@ -0,0 +1,144 @@
+/*
+ * Run Control and Power Management (RCPM) driver
+ *
+ * Copyright 2016 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.
+ *
+ * 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.
+ *
+ */
+#define pr_fmt(fmt) "RCPM: %s: " fmt, __func__
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* So far there are not more than two registers */
+#define RCPM_IPPDEXPCR00x140
+#define RCPM_IPPDEXPCR10x144
+#define RCPM_IPPDEXPCR(x)  (RCPM_IPPDEXPCR0 + 4 * x)
+#define RCPM_WAKEUP_CELL_MAX_SIZE  2
+
+/* it reprents the number of the registers RCPM_IPPDEXPCR */
+static unsigned int rcpm_wakeup_cells;
+static void __iomem *rcpm_reg_base;
+static u32 ippdexpcr[RCPM_WAKEUP_CELL_MAX_SIZE];
+
+static inline void rcpm_reg_write(u32 offset, u32 value)
+{
+   iowrite32be(value, rcpm_reg_base + offset);
+}
+
+static inline u32 rcpm_reg_read(u32 offset)
+{
+   return ioread32be(rcpm_reg_base + offset);
+}
+
+static void rcpm_wakeup_fixup(struct device *dev, void *data)
+{
+   struct device_node *node = dev ? dev->of_node : NULL;
+   u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1];
+   int ret;
+   int i;
+
+   if (!dev || !node || !device_may_wakeup(dev))
+   return;
+
+   /*
+* Get the values in the "rcpm-wakeup" property.
+* Refer to Documentation/devicetree/bindings/soc/fsl/rcpm.txt
+*/
+   ret = of_property_read_u32_array(node, "rcpm-wakeup",
+value, rcpm_wakeup_cells + 1);
+   if (ret)
+   return;
+
+   pr_debug("wakeup source: the device %s\n", node->full_name);
+
+   for (i = 0; i < rcpm_wakeup_cells; i++)
+   ippdexpcr[i] |= value[i + 1];
+}
+
+static int rcpm_suspend_prepare(void)
+{
+   int i;
+
+   for (i = 0; i < rcpm_wakeup_cells; i++)
+   ippdexpcr[i] = 0;
+
+   dpm_for_each_dev(NULL, rcpm_wakeup_fixup);
+
+   for (i = 0; i < rcpm_wakeup_cells; i++) {
+   rcpm_reg_write(RCPM_IPPDEXPCR(i), ippdexpcr[i]);
+   pr_debug("ippdexpcr%d = 0x%x\n", i, ippdexpcr[i]);
+   }
+
+   return 0;
+}
+
+static int rcpm_suspend_notifier_call(struct notifier_block *bl,
+ unsigned long state,
+ void *unused)
+{
+   switch (state) {
+   case PM_SUSPEND_PREPARE:
+   rcpm_suspend_prepare();
+   break;
+   }
+
+   return NOTIFY_DONE;
+}
+
+static const struct of_device_id rcpm_matches[] = {
+   {
+   .compatible = "fsl,qoriq-rcpm-2.1",
+   },
+   {}
+};
+
+static struct notifier_block rcpm_suspend_notifier = {
+   .notifier_call = rcpm_suspend_notifier_call,
+};
+
+static int __init layerscape_rcpm_init(void)
+{
+   struct device_node *np;
+   int ret;
+
+   np = of_find_matching_node_and_match(NULL, rcpm_matches, NULL);
+   if (!np)
+   return -ENODEV;
+
+   ret = of_property_read_u32_index(np, "fsl,#rcpm-wakeu

[PATCH 1/2] ARM: dts: ls1043a: add a rcpm node

2016-08-01 Thread Chenhui Zhao
LS1043A have a RCPM module (Run Control and Power Management), which
performs all device-level tasks associated with power management.

Signed-off-by: Chenhui Zhao 
---
 arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
index de0323b..43944b7 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -196,6 +196,12 @@
bus-width = <4>;
};
 
+   rcpm: rcpm@1ee2000 {
+   compatible = "fsl,ls1043a-rcpm", "fsl,qoriq-rcpm-2.1";
+   reg = <0x0 0x1ee2000 0x0 0x1000>;
+   fsl,#rcpm-wakeup-cells = <1>;
+   };
+
dspi0: dspi@210 {
compatible = "fsl,ls1043a-dspi", 
"fsl,ls1021a-v1.0-dspi";
#address-cells = <1>;
-- 
1.9.1



[PATCH] powerpc/dts: fix rcpm compatible string

2016-04-15 Thread Chenhui Zhao
For T1040, T1042, T1023, and T1024, they should use the compatible
string "fsl,qoriq-rcpm-2.1".

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/boot/dts/fsl/t1023si-post.dtsi | 2 +-
 arch/powerpc/boot/dts/fsl/t1040si-post.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi 
b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
index 99e421d..6e0b489 100644
--- a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
@@ -263,7 +263,7 @@
};
 
rcpm: global-utilities@e2000 {
-   compatible = "fsl,t1023-rcpm", "fsl,qoriq-rcpm-2.0";
+   compatible = "fsl,t1023-rcpm", "fsl,qoriq-rcpm-2.1";
reg = <0xe2000 0x1000>;
};
 
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi 
b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index e0f4da5..507649e 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -472,7 +472,7 @@
};
 
rcpm: global-utilities@e2000 {
-   compatible = "fsl,t1040-rcpm", "fsl,qoriq-rcpm-2.0";
+   compatible = "fsl,t1040-rcpm", "fsl,qoriq-rcpm-2.1";
reg = <0xe2000 0x1000>;
};
 
-- 
1.9.1



[PATCH v4 1/6] powerpc/mm: any thread in one core can be the first to setup TLB1

2015-12-23 Thread Chenhui Zhao
On e6500, in the case of cpu hotplug, either thread in one core
may be the first thread initilzing the TLB1. The subsequent threads
must not setup it again.

The code is derived from the comment of Scott Wood.

Signed-off-by: Chenhui Zhao 
---
Changes for v4:
* added CONFIG_BOOKE

 arch/powerpc/include/asm/cputhreads.h | 8 
 arch/powerpc/mm/tlb_nohash.c  | 4 +---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/cputhreads.h 
b/arch/powerpc/include/asm/cputhreads.h
index ba42e46..ea96231 100644
--- a/arch/powerpc/include/asm/cputhreads.h
+++ b/arch/powerpc/include/asm/cputhreads.h
@@ -94,6 +94,14 @@ static inline int cpu_last_thread_sibling(int cpu)
return cpu | (threads_per_core - 1);
 }
 
+static inline u32 get_tensr(void)
+{
+#ifdef CONFIG_BOOKE
+   if (cpu_has_feature(CPU_FTR_SMT))
+   return mfspr(SPRN_TENSR);
+#endif
+   return 1;
+}
 
 
 #endif /* _ASM_POWERPC_CPUTHREADS_H */
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index bb04e4d..f466848 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -640,9 +640,7 @@ static void early_init_this_mmu(void)
 * transient mapping would cause problems.
 */
 #ifdef CONFIG_SMP
-   if (cpu != boot_cpuid &&
-   (cpu != cpu_first_thread_sibling(cpu) ||
-cpu == cpu_first_thread_sibling(boot_cpuid)))
+   if (hweight32(get_tensr()) > 1)
map = false;
 #endif
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2,5/5] PowerPC/mpc85xx: Add CPU hotplug support for E6500

2015-08-27 Thread Chenhui Zhao



On Thu, Aug 27, 2015 at 6:42 AM, Scott Wood  
wrote:

On Wed, Aug 26, 2015 at 08:09:48PM +0800, Chenhui Zhao wrote:

 +  .globl  booting_thread_hwid
 +booting_thread_hwid:
 +  .long  INVALID_THREAD_HWID
 +  .align 3


The commit message goes into no detail about the changes you're 
making to

thread handling, nor are there relevant comments.


OK. Will add some comments.




 +/*
 + * r3 = the thread physical id
 + */
 +_GLOBAL(book3e_stop_thread)
 +  li  r4, 1
 +  sld r4, r4, r3
 +  mtspr   SPRN_TENC, r4
 +  isync
 +  blr


Why did the C code not have an isync, if it's required here?


Just make sure "mtspr" has completed before the routine returns.





  _GLOBAL(fsl_secondary_thread_init)
/* Enable branch prediction */
lis r3,BUCSR_INIT@h
 @@ -197,8 +236,10 @@ _GLOBAL(fsl_secondary_thread_init)
 * but the low bit right by two bits so that the cpu numbering is
 * continuous.
 */
 -  mfspr   r3, SPRN_PIR
 -  rlwimi  r3, r3, 30, 2, 30
 +  bl  10f
 +10:   mflrr5
 +  addir5,r5,(booting_thread_hwid - 10b)
 +  lwz r3,0(r5)
mtspr   SPRN_PIR, r3
  #endif


I assume the reason for this is that, unlike the kexec case, the cpu 
has

been reset so PIR has been reset?  Don't make me guess -- document.


We can not rely on the value saved in SPRN_PIR. Every time running 
fsl_secondary_thread_init, SPRN_PIR may not always has a reset value.

Using booting_thread_hwid to ensure SPRN_PIR has a correct value.





 @@ -245,6 +286,30 @@ _GLOBAL(generic_secondary_smp_init)
mr  r3,r24
mr  r4,r25
bl  book3e_secondary_core_init
 +
 +/*
 + * If we want to boot Thread1, start Thread1 and stop Thread0.
 + * Note that only Thread0 will run the piece of code.
 + */


What ensures that only thread 0 runs this?  Especially if we're 
entering

via kdump on thread 1?


This piece of code will be executed only when core resets (Thead0 will 
start first). Thead1 will run fsl_secondary_thread_init() to start.


How can kdump run this on Thread1? I know little about kexec.




s/the piece/this piece/


 +  LOAD_REG_ADDR(r3, booting_thread_hwid)
 +  lwz r4, 0(r3)
 +  cmpwi   r4, INVALID_THREAD_HWID
 +  beq 20f
 +  cmpwr4, r24
 +  beq 20f


Do all cores get released from the spin table before the first thread
gets kicked?


Yes.





 +
 +  /* start Thread1 */
 +  LOAD_REG_ADDR(r5, fsl_secondary_thread_init)
 +  ld  r4, 0(r5)
 +  li  r3, 1
 +  bl  book3e_start_thread
 +
 +  /* stop Thread0 */
 +  li  r3, 0
 +  bl  book3e_stop_thread
 +10:
 +  b   10b
 +20:
  #endif

  generic_secondary_common_init:
 diff --git a/arch/powerpc/platforms/85xx/smp.c 
b/arch/powerpc/platforms/85xx/smp.c

 index 73eb994..61f68ad 100644
 --- a/arch/powerpc/platforms/85xx/smp.c
 +++ b/arch/powerpc/platforms/85xx/smp.c
 @@ -181,17 +181,11 @@ static inline u32 read_spin_table_addr_l(void 
*spin_table)

  static void wake_hw_thread(void *info)
  {
void fsl_secondary_thread_init(void);
 -  unsigned long imsr1, inia1;
 -  int nr = *(const int *)info;
 +  unsigned long inia;
 +  int hw_cpu = get_hard_smp_processor_id(*(const int *)info);

 -  imsr1 = MSR_KERNEL;
 -  inia1 = *(unsigned long *)fsl_secondary_thread_init;
 -
 -  mttmr(TMRN_IMSR1, imsr1);
 -  mttmr(TMRN_INIA1, inia1);
 -  mtspr(SPRN_TENS, TEN_THREAD(1));
 -
 -  smp_generic_kick_cpu(nr);
 +  inia = *(unsigned long *)fsl_secondary_thread_init;
 +  book3e_start_thread(cpu_thread_in_core(hw_cpu), inia);
  }
  #endif

 @@ -279,7 +273,6 @@ static int smp_85xx_kick_cpu(int nr)
int ret = 0;
  #ifdef CONFIG_PPC64
int primary = nr;
 -  int primary_hw = get_hard_smp_processor_id(primary);
  #endif

WARN_ON(nr < 0 || nr >= num_possible_cpus());
 @@ -287,33 +280,43 @@ static int smp_85xx_kick_cpu(int nr)
pr_debug("kick CPU #%d\n", nr);

  #ifdef CONFIG_PPC64
 +  booting_thread_hwid = INVALID_THREAD_HWID;
/* Threads don't use the spin table */
 -  if (cpu_thread_in_core(nr) != 0) {
 -  int primary = cpu_first_thread_sibling(nr);
 +  if (threads_per_core == 2) {
 +  booting_thread_hwid = get_hard_smp_processor_id(nr);


What does setting booting_thread_hwid to INVALID_THREAD_HWID here
accomplish?  If threads_per_core != 2 it would never have been set to
anything else, and if threads_per_core == 2 you immediately overwrite 
it.


booting_thread_hwid is valid only for the case that one core has two 
threads (e6500). For e5500 and e500mc, one core one thread, 
"booting_thread_hwid" is invalid.


"booting_thread_hwid" will determine starting which thread in 
generic_secondary_smp_init().





 +  primary = cpu_first_thread_sibl

Re: [PATCH v2,4/5] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores

2015-08-27 Thread Chenhui Zhao



On Thu, Aug 27, 2015 at 4:55 AM, Scott Wood  
wrote:

On Wed, Aug 26, 2015 at 08:09:47PM +0800, Chenhui Zhao wrote:

 +int check_cpu_dead(unsigned int cpu)
 +{
 +  return per_cpu(cpu_state, cpu) == CPU_DEAD;
 +}


I'm not sure this needs to be a function versus open-coded, but if 
you do
want to make it a function, make it more obvious from the caller side 
by

changing it to:

bool is_cpu_dead(unsigned int cpu);

Otherwise if I see "if (check_cpu_dead(cpu))" I don't know if the
if-block is executed if the CPU is dead or if it isn't.


OK.




 diff --git a/arch/powerpc/platforms/85xx/smp.h 
b/arch/powerpc/platforms/85xx/smp.h

 index 0b20ae3..8ee19a3 100644
 --- a/arch/powerpc/platforms/85xx/smp.h
 +++ b/arch/powerpc/platforms/85xx/smp.h
 @@ -6,6 +6,7 @@
  #ifdef CONFIG_SMP
  void __init mpc85xx_smp_init(void);
  int __init mpc85xx_setup_pmc(void);
 +int __init fsl_rcpm_init(void);
  #else


Why wasn't this added in the patch that added fsl_rcpm_init()?

-Scott


Will move it to there.

Thanks,
-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2,3/5] Powerpc: mpc85xx: refactor the PM operations

2015-08-26 Thread Chenhui Zhao
Freescale CoreNet-based and Non-CoreNet-based platforms require
different PM operations. This patch extracted existing PM operations
on Non-CoreNet-based platforms to a new file which can accommodate
both platforms.
In this way, PM operation codes are clearer structurally.

Signed-off-by: Chenhui Zhao 
Signed-off-by: Tang Yuantian 
---
major changes for v2:
* moved mpc85xx_cpu_die()
* added qoriq_pm_ops->cpu_die() in smp_85xx_mach_cpu_die(). it puts the dying
  cpu in a low power mode

 arch/powerpc/platforms/85xx/Makefile |   1 +
 arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c | 106 +++
 arch/powerpc/platforms/85xx/smp.c|  74 +--
 arch/powerpc/platforms/85xx/smp.h|   1 +
 4 files changed, 127 insertions(+), 55 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c

diff --git a/arch/powerpc/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index 1fe7fb9..7bc86da 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)+= mpc85xx_pm_ops.o
 
 obj-y += common.o
 
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c 
b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
new file mode 100644
index 000..ed356dd
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
@@ -0,0 +1,106 @@
+/*
+ * MPC85xx PM operators
+ *
+ * Copyright 2015 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static struct ccsr_guts __iomem *guts;
+
+static void mpc85xx_irq_mask(int cpu)
+{
+
+}
+
+static void mpc85xx_irq_unmask(int cpu)
+{
+
+}
+
+static void mpc85xx_cpu_die(int cpu)
+{
+   u32 tmp;
+
+   tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
+   mtspr(SPRN_HID0, tmp);
+
+   /* Enter NAP mode. */
+   tmp = mfmsr();
+   tmp |= MSR_WE;
+   asm volatile(
+   "msync\n"
+   "mtmsr %0\n"
+   "isync\n"
+   :
+   : "r" (tmp));
+}
+
+static void mpc85xx_cpu_up_prepare(int cpu)
+{
+
+}
+
+static void mpc85xx_freeze_time_base(bool 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 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", },
+   { .compatible = "fsl,bsc9132-guts", },
+   {},
+};
+
+static const struct fsl_pm_ops mpc85xx_pm_ops = {
+   .freeze_time_base = mpc85xx_freeze_time_base,
+   .irq_mask = mpc85xx_irq_mask,
+   .irq_unmask = mpc85xx_irq_unmask,
+   .cpu_die = mpc85xx_cpu_die,
+   .cpu_up_prepare = mpc85xx_cpu_up_prepare,
+};
+
+int __init mpc85xx_setup_pmc(void)
+{
+   struct device_node *np;
+
+   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("Could not map guts node address\n");
+   return -ENOMEM;
+   }
+   }
+
+   qoriq_pm_ops = &mpc85xx_pm_ops;
+
+   return 0;
+}
diff --git a/arch/powerpc/platforms/85xx/smp.c 
b/arch/powerpc/platforms/85xx/smp.c
index 0b75e8e..f9552b8 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -2,7 +2,7 @@
  * Author: Andy Fleming 
  *Kumar Gala 
  *
- * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc.
+ * Copyright 2006-2008, 2011-2012, 2015 Freescale Semiconductor Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -26,9 +25,9 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -43,24 +42,11 @@ struct epapr_spin_table {
u32 pir;
 };
 
-static

[PATCH v2,2/5] powerpc/rcpm: add RCPM driver

2015-08-26 Thread Chenhui Zhao
There is a RCPM (Run Control/Power Management) in Freescale QorIQ
series processors. The device performs tasks associated with device
run control and power management.

The driver implements some features: mask/unmask irq, enter/exit low
power states, freeze time base, etc.

Signed-off-by: Chenhui Zhao 
Signed-off-by: Tang Yuantian 
---
major changes for v2:
* rcpm_v1_cpu_die() and rcpm_v2_cpu_die() will be executed by the dying cpu.
  this way, more stable

 Documentation/devicetree/bindings/soc/fsl/rcpm.txt |  44 +++
 arch/powerpc/include/asm/fsl_guts.h| 105 ++
 arch/powerpc/include/asm/fsl_pm.h  |  50 +++
 arch/powerpc/platforms/85xx/Kconfig|   1 +
 arch/powerpc/platforms/85xx/common.c   |   3 +
 arch/powerpc/sysdev/Kconfig|   5 +
 arch/powerpc/sysdev/Makefile   |   1 +
 arch/powerpc/sysdev/fsl_rcpm.c | 390 +
 8 files changed, 599 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/fsl/rcpm.txt
 create mode 100644 arch/powerpc/include/asm/fsl_pm.h
 create mode 100644 arch/powerpc/sysdev/fsl_rcpm.c

diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt 
b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
new file mode 100644
index 000..dc52f70
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
@@ -0,0 +1,44 @@
+* Run Control and Power Management
+
+The RCPM performs all device-level tasks associated with device run control
+and power management.
+
+Required properites:
+  - reg : Offset and length of the register set of RCPM block.
+  - compatible : Sould contain a chip-specific RCPM block compatible string
+   and (if applicable) may contain a chassis-version RCPM compatible 
string.
+   Chip-specific strings are of the form "fsl,-rcpm", such as:
+   * "fsl,p2041-rcpm"
+   * "fsl,p3041-rcpm"
+   * "fsl,p4080-rcpm"
+   * "fsl,p5020-rcpm"
+   * "fsl,p5040-rcpm"
+   * "fsl,t4240-rcpm"
+   * "fsl,b4420-rcpm"
+   * "fsl,b4860-rcpm"
+
+   Chassis-version RCPM strings include:
+   * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm
+   * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm
+   * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm
+
+All references to "1.0" and "2.0" refer to the QorIQ chassis version to
+which the chip complies.
+Chassis VersionExample Chips
+------
+1.0p4080, p5020, p5040, p2041, p3041
+2.0t4240, b4860, b4420
+2.1t1040
+
+Example:
+The RCPM node for T4240:
+   rcpm: global-utilities@e2000 {
+   compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0";
+   reg = <0xe2000 0x1000>;
+   };
+
+The RCPM node for P4080:
+   rcpm: global-utilities@e2000 {
+   compatible = "fsl,qoriq-rcpm-1.0";
+   reg = <0xe2000 0x1000>;
+   };
diff --git a/arch/powerpc/include/asm/fsl_guts.h 
b/arch/powerpc/include/asm/fsl_guts.h
index 43b6bb1..a67413c 100644
--- a/arch/powerpc/include/asm/fsl_guts.h
+++ b/arch/powerpc/include/asm/fsl_guts.h
@@ -188,5 +188,110 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts 
__iomem *guts,
 
 #endif
 
+struct ccsr_rcpm_v1 {
+   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 PM Control&Status Register */
+#define RCPM_POWMGTCSR_SLP 0x0002
+   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 */

[PATCH v2,4/5] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores

2015-08-26 Thread Chenhui Zhao
Freescale E500MC and E5500 core-based platforms, like P4080, T1040,
support disabling/enabling CPU dynamically.
This patch adds this feature on those platforms.

Signed-off-by: Chenhui Zhao 
Signed-off-by: Tang Yuantian 
---
major changes for v2:
* factor out smp_85xx_start_cpu()
* move fsl_rcpm_init() into mpc85xx_smp_init() due to the init sequence
* add hard_irq_disable() after local_irq_save(). for platforms that
  implement lazy enabling/disabling of interrupts, call hard_irq_disable()
  to ensure interrupts are disabled physically.

 arch/powerpc/Kconfig  |   2 +-
 arch/powerpc/include/asm/smp.h|   3 +
 arch/powerpc/kernel/smp.c |   7 +-
 arch/powerpc/platforms/85xx/smp.c | 193 ++
 arch/powerpc/platforms/85xx/smp.h |   1 +
 5 files changed, 122 insertions(+), 84 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5ef2711..dd9e252 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -386,7 +386,7 @@ config SWIOTLB
 config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
depends on SMP && (PPC_PSERIES || \
-   PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
+   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/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 825663c..4ff5b71 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -67,6 +67,9 @@ void generic_cpu_die(unsigned int cpu);
 void generic_set_cpu_dead(unsigned int cpu);
 void generic_set_cpu_up(unsigned int cpu);
 int generic_check_cpu_restart(unsigned int cpu);
+int check_cpu_dead(unsigned int cpu);
+#else
+#define generic_set_cpu_up(i)  do { } while (0)
 #endif
 
 #ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index ec9ec20..95111f2 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -427,7 +427,7 @@ void generic_cpu_die(unsigned int cpu)
 
for (i = 0; i < 100; i++) {
smp_rmb();
-   if (per_cpu(cpu_state, cpu) == CPU_DEAD)
+   if (check_cpu_dead(cpu))
return;
msleep(100);
}
@@ -454,6 +454,11 @@ int generic_check_cpu_restart(unsigned int cpu)
return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
 }
 
+int check_cpu_dead(unsigned int cpu)
+{
+   return per_cpu(cpu_state, cpu) == CPU_DEAD;
+}
+
 static bool secondaries_inhibited(void)
 {
return kvm_hv_mode_active();
diff --git a/arch/powerpc/platforms/85xx/smp.c 
b/arch/powerpc/platforms/85xx/smp.c
index f9552b8..73eb994 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -10,6 +10,8 @@
  * option) any later version.
  */
 
+#define pr_fmt(fmt) "smp: %s: " fmt, __func__
+
 #include 
 #include 
 #include 
@@ -52,6 +54,7 @@ static void mpc85xx_give_timebase(void)
unsigned long flags;
 
local_irq_save(flags);
+   hard_irq_disable();
 
while (!tb_req)
barrier();
@@ -100,6 +103,7 @@ static void mpc85xx_take_timebase(void)
unsigned long flags;
 
local_irq_save(flags);
+   hard_irq_disable();
 
tb_req = 1;
while (!tb_valid)
@@ -135,8 +139,31 @@ static void smp_85xx_mach_cpu_die(void)
while (1)
;
 }
+
+static void qoriq_cpu_kill(unsigned int cpu)
+{
+   int i;
+
+   for (i = 0; i < 500; i++) {
+   if (check_cpu_dead(cpu)) {
+#ifdef CONFIG_PPC64
+   paca[cpu].cpu_start = 0;
+#endif
+   return;
+   }
+   msleep(20);
+   }
+   pr_err("CPU%d didn't die...\n", cpu);
+}
 #endif
 
+/*
+ * To keep it compatible with old boot program which uses
+ * cache-inhibit spin table, we need to flush the cache
+ * before accessing spin table to invalidate any staled data.
+ * We also need to flush the cache after writing to spin
+ * table to push data out.
+ */
 static inline void flush_spin_table(void *spin_table)
 {
flush_dcache_range((ulong)spin_table,
@@ -168,51 +195,20 @@ static void wake_hw_thread(void *info)
 }
 #endif
 
-static int smp_85xx_kick_cpu(int nr)
+static int smp_85xx_start_cpu(int cpu)
 {
-   unsigned long flags;
-   const u64 *cpu_rel_addr;
-   __iomem struct epapr_spin_table *spin_table;
+   int ret = 0;
struct device_node *np;
-   int hw_cpu = get_hard_smp_processor_id(nr);
+   const u64 *cpu_rel_addr;
+   unsigned long flags;
int ioremappable;
-   int ret = 0;
-
-   WARN_ON(nr < 0 || nr >= NR_CPUS);
-   WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
-
-   pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
-
-#ifdef CONFIG_PPC64
-  

[PATCH v2,5/5] PowerPC/mpc85xx: Add CPU hotplug support for E6500

2015-08-26 Thread Chenhui Zhao
Support Freescale E6500 core-based platforms, like t4240.
Support disabling/enabling individual CPU thread dynamically.

Signed-off-by: Chenhui Zhao 
---
major changes for v2:
* start Thread1 by Thread0 when we want to boot Thread1 only replacing
  the method of changing cpu physical id

 arch/powerpc/include/asm/cputhreads.h |  9 +
 arch/powerpc/include/asm/smp.h|  1 +
 arch/powerpc/kernel/head_64.S | 69 ++-
 arch/powerpc/platforms/85xx/smp.c | 53 ++-
 arch/powerpc/sysdev/fsl_rcpm.c|  2 +-
 5 files changed, 106 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/include/asm/cputhreads.h 
b/arch/powerpc/include/asm/cputhreads.h
index ba42e46..9920f61 100644
--- a/arch/powerpc/include/asm/cputhreads.h
+++ b/arch/powerpc/include/asm/cputhreads.h
@@ -1,6 +1,7 @@
 #ifndef _ASM_POWERPC_CPUTHREADS_H
 #define _ASM_POWERPC_CPUTHREADS_H
 
+#ifndef __ASSEMBLY__
 #include 
 
 /*
@@ -95,6 +96,14 @@ static inline int cpu_last_thread_sibling(int cpu)
 }
 
 
+#ifdef CONFIG_PPC_BOOK3E
+void book3e_start_thread(int thread, unsigned long addr);
+void book3e_stop_thread(int thread);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#define INVALID_THREAD_HWID0x0fff
 
 #endif /* _ASM_POWERPC_CPUTHREADS_H */
 
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 4ff5b71..a1faa4c 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -200,6 +200,7 @@ extern void generic_secondary_thread_init(void);
 extern unsigned long __secondary_hold_spinloop;
 extern unsigned long __secondary_hold_acknowledge;
 extern char __secondary_hold;
+extern unsigned int booting_thread_hwid;
 
 extern void __early_start(void);
 #endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index d48125d..6df2aa4 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -40,6 +40,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* The physical memory is laid out such that the secondary processor
  * spin code sits at 0x...0x00ff. On server, the vectors follow
@@ -181,6 +182,44 @@ exception_marker:
 #endif
 
 #ifdef CONFIG_PPC_BOOK3E
+   .globl  booting_thread_hwid
+booting_thread_hwid:
+   .long  INVALID_THREAD_HWID
+   .align 3
+/*
+ * start threads in the same cpu
+ * input parameters:
+ * r3 = the thread physical id
+ * r4 = the entry point where thread starts
+ */
+_GLOBAL(book3e_start_thread)
+   LOAD_REG_IMMEDIATE(r5, MSR_KERNEL)
+   cmpi0, r3, 0
+   bne 10f
+   mttmr   TMRN_IMSR0, r5
+   mttmr   TMRN_INIA0, r4
+   b   11f
+10:
+   mttmr   TMRN_IMSR1, r5
+   mttmr   TMRN_INIA1, r4
+11:
+   isync
+   li  r6, 1
+   sld r6, r6, r3
+   mtspr   SPRN_TENS, r6
+   isync
+   blr
+
+/*
+ * r3 = the thread physical id
+ */
+_GLOBAL(book3e_stop_thread)
+   li  r4, 1
+   sld r4, r4, r3
+   mtspr   SPRN_TENC, r4
+   isync
+   blr
+
 _GLOBAL(fsl_secondary_thread_init)
/* Enable branch prediction */
lis r3,BUCSR_INIT@h
@@ -197,8 +236,10 @@ _GLOBAL(fsl_secondary_thread_init)
 * but the low bit right by two bits so that the cpu numbering is
 * continuous.
 */
-   mfspr   r3, SPRN_PIR
-   rlwimi  r3, r3, 30, 2, 30
+   bl  10f
+10:mflrr5
+   addir5,r5,(booting_thread_hwid - 10b)
+   lwz r3,0(r5)
mtspr   SPRN_PIR, r3
 #endif
 
@@ -245,6 +286,30 @@ _GLOBAL(generic_secondary_smp_init)
mr  r3,r24
mr  r4,r25
bl  book3e_secondary_core_init
+
+/*
+ * If we want to boot Thread1, start Thread1 and stop Thread0.
+ * Note that only Thread0 will run the piece of code.
+ */
+   LOAD_REG_ADDR(r3, booting_thread_hwid)
+   lwz r4, 0(r3)
+   cmpwi   r4, INVALID_THREAD_HWID
+   beq 20f
+   cmpwr4, r24
+   beq 20f
+
+   /* start Thread1 */
+   LOAD_REG_ADDR(r5, fsl_secondary_thread_init)
+   ld  r4, 0(r5)
+   li  r3, 1
+   bl  book3e_start_thread
+
+   /* stop Thread0 */
+   li  r3, 0
+   bl  book3e_stop_thread
+10:
+   b   10b
+20:
 #endif
 
 generic_secondary_common_init:
diff --git a/arch/powerpc/platforms/85xx/smp.c 
b/arch/powerpc/platforms/85xx/smp.c
index 73eb994..61f68ad 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -181,17 +181,11 @@ static inline u32 read_spin_table_addr_l(void *spin_table)
 static void wake_hw_thread(void *info)
 {
void fsl_secondary_thread_init(void);
-   unsigned long imsr1, inia1;
-   int nr = *(const int *)info;
+   unsigned long inia;
+   int hw_cpu = get_hard_smp_processor_id(*(const int *)info);
 
-   imsr1 = MSR_KERNEL;
-   inia1 = *(unsigned long *)fsl_secondary_thread_init;
-
-   mttmr(TMRN_IMSR1, imsr1

[PATCH v2,1/5] powerpc/cache: add cache flush operation for various e500

2015-08-26 Thread Chenhui Zhao
Various e500 core have different cache architecture, so they
need different cache flush operations. Therefore, add a callback
function cpu_flush_caches to the struct cpu_spec. The cache flush
operation for the specific kind of e500 is selected at init time.
The callback function will flush all caches inside the current cpu.

Signed-off-by: Chenhui Zhao 
Signed-off-by: Tang Yuantian 
---
 arch/powerpc/include/asm/cacheflush.h |   2 -
 arch/powerpc/include/asm/cputable.h   |  11 +++
 arch/powerpc/kernel/asm-offsets.c |   3 +
 arch/powerpc/kernel/cpu_setup_fsl_booke.S | 112 ++
 arch/powerpc/kernel/cputable.c|   4 ++
 arch/powerpc/kernel/head_fsl_booke.S  |  74 
 arch/powerpc/platforms/85xx/smp.c |   5 +-
 7 files changed, 133 insertions(+), 78 deletions(-)

diff --git a/arch/powerpc/include/asm/cacheflush.h 
b/arch/powerpc/include/asm/cacheflush.h
index 30b35ff..729fde4 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -30,8 +30,6 @@ 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);
 extern void flush_icache_user_range(struct vm_area_struct *vma,
struct page *page, unsigned long addr,
diff --git a/arch/powerpc/include/asm/cputable.h 
b/arch/powerpc/include/asm/cputable.h
index b118072..d89b04a 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -43,6 +43,13 @@ extern int machine_check_e500(struct pt_regs *regs);
 extern int machine_check_e200(struct pt_regs *regs);
 extern int machine_check_47x(struct pt_regs *regs);
 
+#if defined(CONFIG_E500)
+extern void cpu_down_flush_e500v2(void);
+extern void cpu_down_flush_e500mc(void);
+extern void cpu_down_flush_e5500(void);
+extern void cpu_down_flush_e6500(void);
+#endif
+
 /* NOTE WELL: Update identify_cpu() if fields are added or removed! */
 struct cpu_spec {
/* CPU is matched via (PVR & pvr_mask) == pvr_value */
@@ -59,6 +66,10 @@ struct cpu_spec {
unsigned inticache_bsize;
unsigned intdcache_bsize;
 
+#if defined(CONFIG_E500)
+   /* flush caches inside the current cpu */
+   void (*cpu_down_flush)(void);
+#endif
/* number of performance monitor counters */
unsigned intnum_pmcs;
enum powerpc_pmc_type pmc_type;
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 9823057..17b672d 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -373,6 +373,9 @@ int main(void)
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
+#if defined(CONFIG_E500)
+   DEFINE(CPU_DOWN_FLUSH, offsetof(struct cpu_spec, cpu_down_flush));
+#endif
 
DEFINE(pbe_address, offsetof(struct pbe, address));
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S 
b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index dddba3e..462aed9 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -13,11 +13,13 @@
  *
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 _GLOBAL(__e500_icache_setup)
mfspr   r0, SPRN_L1CSR1
@@ -233,3 +235,113 @@ _GLOBAL(__setup_cpu_e5500)
mtlrr5
blr
 #endif
+
+/* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */
+_GLOBAL(flush_dcache_L1)
+   mfmsr   r10
+   wrteei  0
+
+   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(r6, KERNELBASE)
+   mr  r4, r6
+   mtctr   r7
+
+1: lwz r3,0(r4)/* Load... */
+   add r4,r

Re: [PATCH 1/3] Powerpc: mpc85xx: refactor the PM operations

2015-08-06 Thread Chenhui Zhao



On Fri, Aug 7, 2015 at 2:02 AM, Scott Wood  
wrote:

On Thu, 2015-08-06 at 13:54 +0800, Chenhui Zhao wrote:

 On Thu, Aug 6, 2015 at 1:46 PM, Scott Wood 
 wrote:
 > On Thu, 2015-08-06 at 12:20 +0800, Chenhui Zhao wrote:
 > >  On Thu, Aug 6, 2015 at 10:57 AM, Scott Wood
 > > 
 > >  wrote:
 > >  > On Wed, 2015-08-05 at 18:11 +0800, Chenhui Zhao wrote:
 > >  > >  On Tue, Aug 4, 2015 at 4:26 AM, Scott Wood
 > > 
 > >  > >  wrote:
 > >  > >  > On Mon, 2015-08-03 at 19:32 +0800, Chenhui Zhao wrote:
 > >  > >  > >  >
 > >  > >  >
 > >  > >  > >  On Sat, Aug 1, 2015 at 7:59 AM, Scott Wood
 > >  > > 
 > >  > >  > >  wrote:
 > >  > >  >
 > >  > >  > >  >
 > >  > >  > >  > Could you explain irq_mask()?  Why would there 
still be

 > > IRQs
 > >  > >  > > destined
 > >  > >  > >  > for
 > >  > >  > >  > this CPU at this point?
 > >  > >  > >
 > >  > >  > >  This function just masks irq by setting the 
registers in

 > > RCPM
 > >  > > (for
 > >  > >  > >  example, RCPM_CPMIMR, RCPM_CPMCIMR). Actually, all 
irqs to

 > >  > > this CPU
 > >  > >  > >  have been migrated to other CPUs.
 > >  > >  >
 > >  > >  > So why do we need to set those bits in RCPM?  Is it just
 > > caution?
 > >  > >
 > >  > >  Setting these bits can mask interrupts signalled to RCPM 
from

 > > MPIC
 > >  > > as a
 > >  > >  means of
 > >  > >  waking up from a lower power state. So, cores will not be
 > > waked up
 > >  > >  unexpectedly.
 > >  >
 > >  > Why would the MPIC be signalling those interrupts if they've 
been

 > >  > masked at
 > >  > the MPIC?
 > >  >
 > >  > -Scott
 > >  >
 > >
 > >  The interrupts to RCPM from MPIC are IRQ, Machine Check, NMI 
and

 > >  Critical interrupts. Some of them didn't be masked in MPIC.
 >
 > What interrupt could actually happen to a sleeping cpu that this
 > protects
 > against?
 >
 > -Scott

 Not sure. Maybe spurious interrupts or hardware exceptions.


Spurious interrupts happen due to race conditions.  They don't happen 
because
the MPIC is bored and decides to ring a CPU's doorbell and hide in 
the bushes.


If by "hardware exceptions" you mean machine checks, how would such a 
machine

check be generated by a core that is off?

  However, setting them make sure dead cpus can not be waked up 
unexpectedly.


I'm not seeing enough value here to warrant resurrecting the old 
sleep node

stuff.

-Scott


My guess maybe not accurate. My point is that electronic parts don't 
always work as expected. Taking preventative measures can make the 
system more robust. In addition, this step is required in deep sleep 
procedure.


-Chenhui



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] Powerpc: mpc85xx: refactor the PM operations

2015-08-05 Thread Chenhui Zhao



On Thu, Aug 6, 2015 at 1:46 PM, Scott Wood  
wrote:

On Thu, 2015-08-06 at 12:20 +0800, Chenhui Zhao wrote:
 On Thu, Aug 6, 2015 at 10:57 AM, Scott Wood 


 wrote:
 > On Wed, 2015-08-05 at 18:11 +0800, Chenhui Zhao wrote:
 > >  On Tue, Aug 4, 2015 at 4:26 AM, Scott Wood 


 > >  wrote:
 > >  > On Mon, 2015-08-03 at 19:32 +0800, Chenhui Zhao wrote:
 > >  > >  >
 > >  >
 > >  > >  On Sat, Aug 1, 2015 at 7:59 AM, Scott Wood
 > > 
 > >  > >  wrote:
 > >  >
 > >  > >  >
 > >  > >  > Could you explain irq_mask()?  Why would there still be 
IRQs

 > >  > > destined
 > >  > >  > for
 > >  > >  > this CPU at this point?
 > >  > >
 > >  > >  This function just masks irq by setting the registers in 
RCPM

 > > (for
 > >  > >  example, RCPM_CPMIMR, RCPM_CPMCIMR). Actually, all irqs to
 > > this CPU
 > >  > >  have been migrated to other CPUs.
 > >  >
 > >  > So why do we need to set those bits in RCPM?  Is it just 
caution?

 > >
 > >  Setting these bits can mask interrupts signalled to RCPM from 
MPIC

 > > as a
 > >  means of
 > >  waking up from a lower power state. So, cores will not be 
waked up

 > >  unexpectedly.
 >
 > Why would the MPIC be signalling those interrupts if they've been
 > masked at
 > the MPIC?
 >
 > -Scott
 >

 The interrupts to RCPM from MPIC are IRQ, Machine Check, NMI and
 Critical interrupts. Some of them didn't be masked in MPIC.


What interrupt could actually happen to a sleeping cpu that this 
protects

against?

-Scott


Not sure. Maybe spurious interrupts or hardware exceptions. However, 
setting them make sure dead cpus can not be waked up unexpectedly.


-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] PowerPC/mpc85xx: Add hotplug support on E6500 cores

2015-08-05 Thread Chenhui Zhao



On Thu, Aug 6, 2015 at 11:16 AM, Scott Wood  
wrote:

On Wed, 2015-08-05 at 19:08 +0800, Chenhui Zhao wrote:

 On Sat, Aug 1, 2015 at 8:22 AM, Scott Wood 
 wrote:
 > On Fri, 2015-07-31 at 17:20 +0800,  b29983@freescale.comwrote:
 > >  + /*
 > >  +  * If both threads are offline, reset core to 
start.
 > >  +  * When core is up, Thread 0 always gets up 
first,

 > >  +  * so bind the current logical cpu with Thread 0.
 > >  +  */
 > >  + if (hw_cpu != cpu_first_thread_sibling(hw_cpu)) {
 > >  + int hw_cpu1, hw_cpu2;
 > >  +
 > >  + hw_cpu1 = 
get_hard_smp_processor_id(primary);
 > >  + hw_cpu2 = 
get_hard_smp_processor_id(primary +

 > > 1);
 > >  + set_hard_smp_processor_id(primary, 
hw_cpu2);

 > >  + set_hard_smp_processor_id(primary + 1,
 > > hw_cpu1);
 > >  + /* get new physical cpu id */
 > >  + hw_cpu = get_hard_smp_processor_id(nr);
 >
 > NACK as discussed in http://patchwork.ozlabs.org/patch/454944/
 >
 > -Scott

 You said,

 There's no need for this. I have booting from a thread1, and 
having

 it
 kick its thread0, working locally without messing with the 
hwid/cpu

 mapping.

 I still have questions here. After a core reset, how can you boot
 Thread1
 of the core first. As I know, Thread0 boots up first by default.


So the issue isn't that thread1 comes up first, but that you *want* 
thread1
to come up first and it won't.  I don't think this remapping is an 
acceptable
answer, though.  Instead, if you need only thread1 to come up, start 
the
core, have thread0 start thread1, and then send thread0 into whatever 
waiting

state it would be in if thread1 had never been offlined.

-Scott


Remapping is a concise solution. what's the harm of it?
Keeping things simple is good in my opinion.

-Chenhui



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] Powerpc: mpc85xx: refactor the PM operations

2015-08-05 Thread Chenhui Zhao



On Thu, Aug 6, 2015 at 10:57 AM, Scott Wood  
wrote:

On Wed, 2015-08-05 at 18:11 +0800, Chenhui Zhao wrote:

 On Tue, Aug 4, 2015 at 4:26 AM, Scott Wood 
 wrote:
 > On Mon, 2015-08-03 at 19:32 +0800, Chenhui Zhao wrote:
 > >  >
 >
 > >  On Sat, Aug 1, 2015 at 7:59 AM, Scott Wood 


 > >  wrote:
 >
 > >  >
 > >  > Could you explain irq_mask()?  Why would there still be IRQs
 > > destined
 > >  > for
 > >  > this CPU at this point?
 > >
 > >  This function just masks irq by setting the registers in RCPM 
(for
 > >  example, RCPM_CPMIMR, RCPM_CPMCIMR). Actually, all irqs to 
this CPU

 > >  have been migrated to other CPUs.
 >
 > So why do we need to set those bits in RCPM?  Is it just caution?

 Setting these bits can mask interrupts signalled to RCPM from MPIC 
as a

 means of
 waking up from a lower power state. So, cores will not be waked up
 unexpectedly.


Why would the MPIC be signalling those interrupts if they've been 
masked at

the MPIC?

-Scott



The interrupts to RCPM from MPIC are IRQ, Machine Check, NMI and 
Critical interrupts. Some of them didn't be masked in MPIC.


-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] PowerPC/mpc85xx: Add hotplug support on E6500 cores

2015-08-05 Thread Chenhui Zhao



On Sat, Aug 1, 2015 at 8:22 AM, Scott Wood  
wrote:

On Fri, 2015-07-31 at 17:20 +0800, b29...@freescale.com wrote:

 diff --git a/arch/powerpc/platforms/85xx/smp.c
 b/arch/powerpc/platforms/85xx/smp.c
 index 7f0dadb..8652a49 100644
 --- a/arch/powerpc/platforms/85xx/smp.c
 +++ b/arch/powerpc/platforms/85xx/smp.c
 @@ -189,15 +189,22 @@ static inline u32 read_spin_table_addr_l(void
 *spin_table)
  static void wake_hw_thread(void *info)
  {
   void fsl_secondary_thread_init(void);
 - unsigned long imsr1, inia1;
 + unsigned long imsr, inia;
   int nr = *(const int *)info;
 -
 - imsr1 = MSR_KERNEL;
 - inia1 = *(unsigned long *)fsl_secondary_thread_init;
 -
 - mttmr(TMRN_IMSR1, imsr1);
 - mttmr(TMRN_INIA1, inia1);
 - mtspr(SPRN_TENS, TEN_THREAD(1));
 + int hw_cpu = get_hard_smp_processor_id(nr);
 + int thread_idx = cpu_thread_in_core(hw_cpu);
 +
 + booting_cpu_hwid = (u32)hw_cpu;


Unnecessary cast.  Please explain why you need booting_cpu_hwid.



 + imsr = MSR_KERNEL;
 + inia = *(unsigned long *)fsl_secondary_thread_init;
 + if (thread_idx == 0) {
 + mttmr(TMRN_IMSR0, imsr);
 + mttmr(TMRN_INIA0, inia);
 + } else {
 + mttmr(TMRN_IMSR1, imsr);
 + mttmr(TMRN_INIA1, inia);
 + }
 + mtspr(SPRN_TENS, TEN_THREAD(thread_idx));


Please rebase this on top of http://patchwork.ozlabs.org/patch/496952/


OK.





 + /*
 +  * If both threads are offline, reset core to start.
 +  * When core is up, Thread 0 always gets up first,
 +  * so bind the current logical cpu with Thread 0.
 +  */
 + if (hw_cpu != cpu_first_thread_sibling(hw_cpu)) {
 + int hw_cpu1, hw_cpu2;
 +
 + hw_cpu1 = get_hard_smp_processor_id(primary);
 + hw_cpu2 = get_hard_smp_processor_id(primary + 
1);

 + set_hard_smp_processor_id(primary, hw_cpu2);
 + set_hard_smp_processor_id(primary + 1, 
hw_cpu1);

 + /* get new physical cpu id */
 + hw_cpu = get_hard_smp_processor_id(nr);


NACK as discussed in http://patchwork.ozlabs.org/patch/454944/

-Scott


You said,

   There's no need for this. I have booting from a thread1, and having 
it

   kick its thread0, working locally without messing with the hwid/cpu
   mapping.

I still have questions here. After a core reset, how can you boot 
Thread1

of the core first. As I know, Thread0 boots up first by default.

-Chenhui





--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores

2015-08-05 Thread Chenhui Zhao



On Tue, Aug 4, 2015 at 5:18 AM, Scott Wood  
wrote:
[Added linuxppc-...@lists.ozlabs.org.  Besides that list being 
required for
review of PPC patches, it feeds the patchwork that I use to track and 
apply

patches.]

On Mon, 2015-08-03 at 19:52 +0800, Chenhui Zhao wrote:

 On Sat, Aug 1, 2015 at 8:14 AM, Scott Wood 
 wrote:
 > On Fri, 2015-07-31 at 17:20 +0800,  b29983@freescale.comwrote:
 > >  From: Tang Yuantian 
 > >
 > >  Freescale E500MC and E5500 core-based platforms, like P4080, 
T1040,

 > >  support disabling/enabling CPU dynamically.
 > >  This patch adds this feature on those platforms.
 > >
 > >  Signed-off-by: Chenhui Zhao 
 > >  Signed-off-by: Tang Yuantian 




 +{
 > >  + int i;
 > >  +
 > >  + for (i = 0; i < 5; i++) {
 > >  + if (generic_check_cpu_dead(cpu)) {
 > >  + qoriq_pm_ops->cpu_die(cpu);
 > >  +#ifdef CONFIG_PPC64
 > >  + paca[cpu].cpu_start = 0;
 > >  +#endif
 > >  + return;
 > >  + }
 > >  + udelay(10);
 > >  + }
 > >  + pr_err("%s: CPU%d didn't die...\n", __func__, cpu);
 > >  +}
 >
 > Only 500ms timeout, versus 10sec in generic_cpu_die()?

 The process is fast. Maybe 10 second is too large.


Is it fast 100% of the time?  What if the CPU you intend to die is in 
a long
critical section?  What harm is there to having a longer timeout, 
similar to

what other platforms use?


Will change the max timeout to 10 seconds.





 >
 > >   #endif
 > >
 > >   static inline void flush_spin_table(void *spin_table)
 > >  @@ -246,11 +267,7 @@ static int 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) {
 > >/*
 > > * To keep it compatible with old boot program 
which

 > > uses
 > >  @@ -263,6 +280,7 @@ static int smp_85xx_kick_cpu(int nr)
 > >out_be32(&spin_table->addr_l, 0);
 > >flush_spin_table(spin_table);
 > >
 > >  + qoriq_pm_ops->cpu_up(nr);
 >
 > Again, is it possible to get here without a valid qoriq_pm_ops 
(i.e.

 > is there
 > anything stopping the user from trying to initiate CPU hotplug)?
 >
 > -Scott

 For every platform running this code, should has a valid 
qoriq_pm_ops.

 If not valid, it's a bug.


How do you prevent this code from running when there is no valid 
qoriq_pm_ops?


-Scott



Will check if qoriq_pm_ops is valid.

-Chenhui



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] Powerpc: mpc85xx: refactor the PM operations

2015-08-05 Thread Chenhui Zhao



On Tue, Aug 4, 2015 at 4:26 AM, Scott Wood  
wrote:

On Mon, 2015-08-03 at 19:32 +0800, Chenhui Zhao wrote:

 >



 On Sat, Aug 1, 2015 at 7:59 AM, Scott Wood 
 wrote:



 >
 > Could you explain irq_mask()?  Why would there still be IRQs 
destined

 > for
 > this CPU at this point?

 This function just masks irq by setting the registers in RCPM (for
 example, RCPM_CPMIMR, RCPM_CPMCIMR). Actually, all irqs to this CPU
 have been migrated to other CPUs.


So why do we need to set those bits in RCPM?  Is it just caution?


Setting these bits can mask interrupts signalled to RCPM from MPIC as a 
means of
waking up from a lower power state. So, cores will not be waked up 
unexpectedly.





 > @@ -431,21 +415,9 @@ void __init mpc85xx_smp_init(void)
 > >smp_85xx_ops.probe = NULL;
 > >}
 > >
 > >  - 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;

 > >   #ifdef CONFIG_HOTPLUG_CPU
 > >  - ppc_md.cpu_die = smp_85xx_mach_cpu_die;
 > >  + ppc_md.cpu_die = qoriq_cpu_dying;
 > >   #endif
 >
 > Shouldn't you make sure there's a valid qoriq_pm_ops before 
setting

 > cpu_die()?  Or make sure that qoriq_cpu_dying() works regardless.
 >
 > -Scott

 This patch is just for e500v2. The following patches will handle the
 case of e500mc, e5500 and e6500.


What stops a user from trying to use cpu hotplug on unsupported cpus, 
or in a

virtualized environment, and crashing here?

-Scott


Will set these callback functions only if qoriq_pm_ops is valid.

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5] powerpc/rcpm: add RCPM driver

2015-08-03 Thread Chenhui Zhao



On Tue, Aug 4, 2015 at 4:23 AM, Scott Wood  
wrote:

On Mon, 2015-08-03 at 19:14 +0800, Chenhui Zhao wrote:

 On Sat, Aug 1, 2015 at 8:45 AM, Scott Wood 
 wrote:
 > On Fri, 2015-06-26 at 15:44 +0800,  
Yuantian.Tang@freescale.comwrote:

 > >  +static void rcpm_v1_set_ip_power(bool enable, u32 *mask)
 > >  +{
 > >  + if (enable)
 > >  + setbits32(&rcpm_v1_regs->ippdexpcr, *mask);
 > >  + else
 > >  + clrbits32(&rcpm_v1_regs->ippdexpcr, *mask);
 > >  +}
 > >  +
 > >  +static void rcpm_v2_set_ip_power(bool enable, u32 *mask)
 > >  +{
 > >  + if (enable)
 > >  + setbits32(&rcpm_v2_regs->ippdexpcr[0], *mask);
 > >  + else
 > >  + clrbits32(&rcpm_v2_regs->ippdexpcr[0], *mask);
 > >  +}
 >
 > Why do these take "u32 *mask" instead of "u32 mask"?
 >
 > -Scott

 I think it can be used in the case where there are several mask 
values.


When would that be?

-Scott


So far, only use one register, even though the register name is 
"IPPDEXPCRn" (has "n" suffix) in T4 RM.


OK. Just change the parameter to "u32 mask".

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/4] powerpc: pm: add EPU FSM configuration for deep sleep

2015-08-03 Thread Chenhui Zhao



On Sat, Aug 1, 2015 at 8:41 AM, Scott Wood  
wrote:

On Fri, 2015-07-31 at 20:53 +0800, Chenhui Zhao wrote:

 In the last stage of deep sleep, software will trigger a Finite
 State Machine (FSM) to control the hardware precedure, such as
 board isolation, killing PLLs, removing power, and so on.

 When the system is waked up by an interrupt, the FSM controls the
 hardware to complete the early resume precedure.

 This patch configure the EPU FSM preparing for deep sleep.

 Signed-off-by: Chenhui Zhao 
 ---
  arch/powerpc/platforms/85xx/Makefile|   2 +-
  arch/powerpc/platforms/85xx/sleep_fsm.c | 256
 
  arch/powerpc/platforms/85xx/sleep_fsm.h | 104 +
  3 files changed, 361 insertions(+), 1 deletion(-)
  create mode 100644 arch/powerpc/platforms/85xx/sleep_fsm.c
  create mode 100644 arch/powerpc/platforms/85xx/sleep_fsm.h


When I asked why this was in drivers/platform[1], you said it was to 
share
with LS1, and that the values used were the same -- so why did you 
move it to

arch/powerpc?


There are some changes. LS1 will use PSCI (Power State Coordination 
Interface) to implement deep sleep. So these code just used by PowerPC.




[1] Note that other proposed patches create a drivers/soc/fsl instead 
of

drivers/platform/fsl...  We need one of them, not both.


 +void fsl_fsm_setup(void __iomem *base, struct fsm_reg_vals *val)
 +{
 + struct fsm_reg_vals *data = val;
 +
 + BUG_ON(!base || !data);


This BUG_ON is useless.  If one of those is NULL you'll get an oops 
anyway.




 diff --git a/arch/powerpc/platforms/85xx/sleep_fsm.h
 b/arch/powerpc/platforms/85xx/sleep_fsm.h
 new file mode 100644
 index 000..2c60b40
 --- /dev/null
 +++ b/arch/powerpc/platforms/85xx/sleep_fsm.h
 @@ -0,0 +1,104 @@
 +/*
 + * Freescale deep sleep FSM (finite-state machine) configuration
 + *
 + * Copyright 2015 Freescale Semiconductor Inc.
 + *
 + * This program is free software; you can redistribute  it and/or 
modify it
 + * under  the terms of  the GNU General  Public License as 
published by the
 + * Free Software Foundation;  either version 2 of the  License, or 
(at your

 + * option) any later version.
 + */
 +#ifndef _FSL_SLEEP_FSM_H
 +#define _FSL_SLEEP_FSM_H
 +
 +#define FSL_STRIDE_4B4
 +#define FSL_STRIDE_8B8


Why not just use 4/8 directly?



 +/* Block offsets */
 +#define RCPM_BLOCK_OFFSET0x00022000
 +#define EPU_BLOCK_OFFSET 0x
 +#define NPC_BLOCK_OFFSET 0x1000


I thought you said OK to not putting these offsets in the kernel 
source...


-Scott


OK. Will change them.

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores

2015-08-03 Thread Chenhui Zhao



On Sat, Aug 1, 2015 at 8:14 AM, Scott Wood  
wrote:

On Fri, 2015-07-31 at 17:20 +0800, b29...@freescale.com wrote:

 From: Tang Yuantian 

 Freescale E500MC and E5500 core-based platforms, like P4080, T1040,
 support disabling/enabling CPU dynamically.
 This patch adds this feature on those platforms.

 Signed-off-by: Chenhui Zhao 
 Signed-off-by: Tang Yuantian 
 ---
  arch/powerpc/Kconfig  |  2 +-
  arch/powerpc/include/asm/smp.h|  1 +
  arch/powerpc/kernel/smp.c |  5 +
  arch/powerpc/platforms/85xx/smp.c | 39 


 ---
  4 files changed, 39 insertions(+), 8 deletions(-)

 diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
 index 5ef2711..dd9e252 100644
 --- a/arch/powerpc/Kconfig
 +++ b/arch/powerpc/Kconfig
 @@ -386,7 +386,7 @@ config SWIOTLB
  config HOTPLUG_CPU
   bool "Support for enabling/disabling CPUs"
   depends on SMP && (PPC_PSERIES || \
 - PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
 + 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/include/asm/smp.h 
b/arch/powerpc/include/asm/smp.h

 index 825663c..bf37d17 100644
 --- a/arch/powerpc/include/asm/smp.h
 +++ b/arch/powerpc/include/asm/smp.h
 @@ -67,6 +67,7 @@ void generic_cpu_die(unsigned int cpu);
  void generic_set_cpu_dead(unsigned int cpu);
  void generic_set_cpu_up(unsigned int cpu);
  int generic_check_cpu_restart(unsigned int cpu);
 +int generic_check_cpu_dead(unsigned int cpu);
  #endif

  #ifdef CONFIG_PPC64
 diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
 index ec9ec20..2cca27a 100644
 --- a/arch/powerpc/kernel/smp.c
 +++ b/arch/powerpc/kernel/smp.c
 @@ -454,6 +454,11 @@ int generic_check_cpu_restart(unsigned int cpu)
   return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
  }

 +int generic_check_cpu_dead(unsigned int cpu)
 +{
 + return per_cpu(cpu_state, cpu) == CPU_DEAD;
 +}


Is there a non-generic check_cpu_dead()?


NO, just follow the name "generic_check_cpu_restart()".



It gets open-coded in generic_cpu_die()... Either open-code it 
elsewhere, or
call it check_cpu_dead() and use it everywhere there's a CPU_DEAD 
check.




 +
  static bool secondaries_inhibited(void)
  {
   return kvm_hv_mode_active();
 diff --git a/arch/powerpc/platforms/85xx/smp.c
 b/arch/powerpc/platforms/85xx/smp.c
 index 6811a5b..7f0dadb 100644
 --- a/arch/powerpc/platforms/85xx/smp.c
 +++ b/arch/powerpc/platforms/85xx/smp.c
 @@ -42,6 +42,7 @@ struct epapr_spin_table {
   u32 pir;
  };

 +#ifdef CONFIG_HOTPLUG_CPU
  static u64 timebase;
  static int tb_req;
  static int tb_valid;
 @@ -111,7 +112,7 @@ static void mpc85xx_take_timebase(void)
   local_irq_restore(flags);
  }

 -#ifdef CONFIG_HOTPLUG_CPU
 +#ifndef CONFIG_PPC_E500MC
  static void e500_cpu_idle(void)


What happens if we bisect to patch 1/3 and run this on e500mc?

Please move the ifdef to that patch.


OK.





  {
   u32 tmp;
 @@ -127,6 +128,7 @@ static void e500_cpu_idle(void)
   mtmsr(tmp);
   isync();
  }
 +#endif

  static void qoriq_cpu_dying(void)
  {
 @@ -144,11 +146,30 @@ static void qoriq_cpu_dying(void)

   generic_set_cpu_dead(cpu);

 +#ifndef CONFIG_PPC_E500MC
   e500_cpu_idle();
 +#endif

   while (1)
   ;
  }
 +
 +static void qoriq_real_cpu_die(unsigned int cpu)


Real as opposed to...?


It's hard to find a good name. :)





 +{
 + int i;
 +
 + for (i = 0; i < 5; i++) {
 + if (generic_check_cpu_dead(cpu)) {
 + qoriq_pm_ops->cpu_die(cpu);
 +#ifdef CONFIG_PPC64
 + paca[cpu].cpu_start = 0;
 +#endif
 + return;
 + }
 + udelay(10);
 + }
 + pr_err("%s: CPU%d didn't die...\n", __func__, cpu);
 +}


Only 500ms timeout, versus 10sec in generic_cpu_die()?


The process is fast. Maybe 10 second is too large.




  #endif

  static inline void flush_spin_table(void *spin_table)
 @@ -246,11 +267,7 @@ static int 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) {
   /*
* To keep it compatible with old boot program which 
uses

 @@ -263,6 +280,7 @@ static int smp_85xx_kick_cpu(int nr)
   out_be32(&spin_table->addr_l, 0);
   flush_spin_table(spin_table);

 + qoriq_pm_ops->cpu_up(nr);


Again, is it possible to get here without a valid qoriq_pm_ops (i.e. 
is there

anything stopping the user from trying to initiate CPU hotplug)?

-Scott


For every platform running this code, 

Re: [PATCH 1/3] Powerpc: mpc85xx: refactor the PM operations

2015-08-03 Thread Chenhui Zhao



On Sat, Aug 1, 2015 at 7:59 AM, Scott Wood  
wrote:

On Fri, 2015-07-31 at 17:20 +0800, b29...@freescale.com wrote:

 @@ -71,7 +56,7 @@ static void mpc85xx_give_timebase(void)
   barrier();
   tb_req = 0;

 - mpc85xx_timebase_freeze(1);
 + qoriq_pm_ops->freeze_time_base(1);


freeze_time_base() takes a bool.  Use true/false.


OK.





  #ifdef CONFIG_PPC64
   /*
* e5500/e6500 have a workaround for erratum A-006958 in place
 @@ -104,7 +89,7 @@ static void mpc85xx_give_timebase(void)
   while (tb_valid)
   barrier();

 - mpc85xx_timebase_freeze(0);
 + qoriq_pm_ops->freeze_time_base(0);

   local_irq_restore(flags);
  }
 @@ -127,20 +112,10 @@ static void mpc85xx_take_timebase(void)
  }

  #ifdef CONFIG_HOTPLUG_CPU
 -static void smp_85xx_mach_cpu_die(void)
 +static void e500_cpu_idle(void)


This is not the function that gets called during normal cpu idle, and 
it

shouldn't be named to look like it is.


Sorry, it's a typo. It shoule be "e500_cpu_die".




  {
 - unsigned int cpu = smp_processor_id();
   u32 tmp;

 - local_irq_disable();
 - idle_task_exit();
 - generic_set_cpu_dead(cpu);
 - mb();
 -
 - mtspr(SPRN_TCR, 0);
 -
 - cur_cpu_spec->cpu_down_flush();
 -
   tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
   mtspr(SPRN_HID0, tmp);
   isync();
 @@ -151,6 +126,25 @@ static void smp_85xx_mach_cpu_die(void)
   mb();
   mtmsr(tmp);
   isync();
 +}
 +
 +static void qoriq_cpu_dying(void)
 +{
 + unsigned int cpu = smp_processor_id();
 +
 + hard_irq_disable();
 + /* mask all irqs to prevent cpu wakeup */
 + qoriq_pm_ops->irq_mask(cpu);
 + idle_task_exit();
 +
 + mtspr(SPRN_TCR, 0);
 + mtspr(SPRN_TSR, mfspr(SPRN_TSR));
 +
 + cur_cpu_spec->cpu_down_flush();
 +
 + generic_set_cpu_dead(cpu);
 +
 + e500_cpu_idle();


Why is something that claims to be applicable to all qoriq directly 
calling

an e500v2-specific function?


Added "#ifndef CONFIG_PPC_E500MC" in the following patch.



Could you explain irq_mask()?  Why would there still be IRQs destined 
for

this CPU at this point?


This function just masks irq by setting the registers in RCPM (for 
example, RCPM_CPMIMR, RCPM_CPMCIMR). Actually, all irqs to this CPU 
have been migrated to other CPUs.




@@ -431,21 +415,9 @@ void __init mpc85xx_smp_init(void)

   smp_85xx_ops.probe = NULL;
   }

 - 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;
  #ifdef CONFIG_HOTPLUG_CPU
 - ppc_md.cpu_die = smp_85xx_mach_cpu_die;
 + ppc_md.cpu_die = qoriq_cpu_dying;
  #endif


Shouldn't you make sure there's a valid qoriq_pm_ops before setting
cpu_die()?  Or make sure that qoriq_cpu_dying() works regardless.

-Scott


This patch is just for e500v2. The following patches will handle the 
case of e500mc, e5500 and e6500.


-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5] powerpc/rcpm: add RCPM driver

2015-08-03 Thread Chenhui Zhao



On Sat, Aug 1, 2015 at 8:45 AM, Scott Wood  
wrote:

On Fri, 2015-06-26 at 15:44 +0800, yuantian.t...@freescale.com wrote:

 +static void rcpm_v1_set_ip_power(bool enable, u32 *mask)
 +{
 + if (enable)
 + setbits32(&rcpm_v1_regs->ippdexpcr, *mask);
 + else
 + clrbits32(&rcpm_v1_regs->ippdexpcr, *mask);
 +}
 +
 +static void rcpm_v2_set_ip_power(bool enable, u32 *mask)
 +{
 + if (enable)
 + setbits32(&rcpm_v2_regs->ippdexpcr[0], *mask);
 + else
 + clrbits32(&rcpm_v2_regs->ippdexpcr[0], *mask);
 +}


Why do these take "u32 *mask" instead of "u32 mask"?

-Scott


I think it can be used in the case where there are several mask values.

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] powerpc/85xx: add sleep and deep sleep support

2015-08-03 Thread Chenhui Zhao



On Sat, Aug 1, 2015 at 10:57 AM, Scott Wood  
wrote:

On Fri, 2015-07-24 at 20:46 +0800, Chenhui Zhao wrote:

 +static void mpc85xx_pmc_set_wake(struct device *dev, void *enable)
  {
   int ret;
 + u32 value[2];
 +
 + if (!device_may_wakeup(dev))
 + return;
 +
 + if (!pmc_regs) {
 + dev_err(dev, "%s: PMC is unavailable\n", __func__);
 + return;
 + }
 +
 + ret = of_property_read_u32_array(dev->of_node, "sleep", 
value, 2);


This will crash on any device without an of_node.


Add this before this line:
if (!dev->of_node)
return;





 + if (ret) {
 + dev_dbg(dev, "%s: Can not find the \"sleep\" 
property.\n",

 + __func__);
 + return;
 + }
 +
 + if (*(int *)enable)
 + pmc_pmcdr_mask &= ~value[1];
 + else
 + pmc_pmcdr_mask |= value[1];
 +
 + if ((value[1] & 0xe0) && (pmc_flag & PMC_LOSSLESS))
 + pmc_powmgtcsr = POWMGTCSR_LOSSLESS;
 +}


What is 0xe0?

-Scott


This is a mask value for the register PMCDR, which includes all bits 
corresponding to eTSEC. Will use a macro instead.


-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/4] powerpc: get the physical base address of DCSR

2015-07-31 Thread Chenhui Zhao
Add get_dcsrbase() to get the physical base address of DCSR.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/sysdev/fsl_soc.c | 31 +++
 arch/powerpc/sysdev/fsl_soc.h |  1 +
 2 files changed, 32 insertions(+)

diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 99269c0..ffb7c1c 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -45,6 +45,37 @@ extern void init_fcc_ioports(struct fs_platform_info*);
 extern void init_fec_ioports(struct fs_platform_info*);
 extern void init_smc_ioports(struct fs_uart_platform_info*);
 static phys_addr_t immrbase = -1;
+static phys_addr_t dcsrbase = -1;
+
+phys_addr_t get_dcsrbase(void)
+{
+   struct device_node *np;
+   const __be32 *prop;
+   int size;
+   u32 naddr;
+
+   if (dcsrbase != -1)
+   return dcsrbase;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,dcsr");
+   if (!np)
+   return -1;
+
+   prop = of_get_property(np, "#address-cells", &size);
+   if (prop && size == 4)
+   naddr = be32_to_cpup(prop);
+   else
+   naddr = 2;
+
+   prop = of_get_property(np, "ranges", NULL);
+   if (prop)
+   dcsrbase = of_translate_address(np, prop + naddr);
+
+   of_node_put(np);
+
+   return dcsrbase;
+}
+EXPORT_SYMBOL(get_dcsrbase);
 
 phys_addr_t get_immrbase(void)
 {
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 4c5a19e..5fdd3a5 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -6,6 +6,7 @@
 
 struct spi_device;
 
+extern phys_addr_t get_dcsrbase(void);
 extern phys_addr_t get_immrbase(void);
 #if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx)
 extern u32 get_brgfreq(void);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/4] powerpc: pm: add EPU FSM configuration for deep sleep

2015-07-31 Thread Chenhui Zhao
In the last stage of deep sleep, software will trigger a Finite
State Machine (FSM) to control the hardware precedure, such as
board isolation, killing PLLs, removing power, and so on.

When the system is waked up by an interrupt, the FSM controls the
hardware to complete the early resume precedure.

This patch configure the EPU FSM preparing for deep sleep.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/platforms/85xx/Makefile|   2 +-
 arch/powerpc/platforms/85xx/sleep_fsm.c | 256 
 arch/powerpc/platforms/85xx/sleep_fsm.h | 104 +
 3 files changed, 361 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/platforms/85xx/sleep_fsm.c
 create mode 100644 arch/powerpc/platforms/85xx/sleep_fsm.h

diff --git a/arch/powerpc/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index fdae28b..87fb847 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -3,7 +3,7 @@
 #
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_FSL_PMC)+= mpc85xx_pm_ops.o
-obj-$(CONFIG_FSL_QORIQ_PM)   += qoriq_pm.o
+obj-$(CONFIG_FSL_QORIQ_PM)   += qoriq_pm.o sleep_fsm.o
 
 obj-y += common.o
 
diff --git a/arch/powerpc/platforms/85xx/sleep_fsm.c 
b/arch/powerpc/platforms/85xx/sleep_fsm.c
new file mode 100644
index 000..2e81d37
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/sleep_fsm.c
@@ -0,0 +1,256 @@
+/*
+ * Freescale deep sleep FSM (finite-state machine) configuration
+ *
+ * Copyright 2015 Freescale Semiconductor Inc.
+ *
+ * Author: Hongbo Zhang 
+ * Chenhui Zhao 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#include "sleep_fsm.h"
+/*
+ * These values are from chip's reference manual. For example,
+ * the values for T1040 can be found in "8.4.3.8 Programming
+ * supporting deep sleep mode" of Chapter 8 "Run Control and
+ * Power Management (RCPM)".
+ * The default value can be applied to T104x, LS1021.
+ */
+struct fsm_reg_vals epu_default_val[] = {
+   /* EPGCR (Event Processor Global Control Register) */
+   {EPGCR, 0},
+   /* EPECR (Event Processor Event Control Registers) */
+   {EPECR0 + EPECR_STRIDE * 0, 0},
+   {EPECR0 + EPECR_STRIDE * 1, 0},
+   {EPECR0 + EPECR_STRIDE * 2, 0xF0004004},
+   {EPECR0 + EPECR_STRIDE * 3, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 4, 0x2084},
+   {EPECR0 + EPECR_STRIDE * 5, 0x0804},
+   {EPECR0 + EPECR_STRIDE * 6, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 7, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 8, 0x6084},
+   {EPECR0 + EPECR_STRIDE * 9, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 10, 0x4284},
+   {EPECR0 + EPECR_STRIDE * 11, 0x9084},
+   {EPECR0 + EPECR_STRIDE * 12, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 13, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 14, 0x0284},
+   {EPECR0 + EPECR_STRIDE * 15, 0x0004},
+   /*
+* EPEVTCR (Event Processor EVT Pin Control Registers)
+* SCU8 triger EVT2, and SCU11 triger EVT9
+*/
+   {EPEVTCR0 + EPEVTCR_STRIDE * 0, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 1, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 2, 0x8001},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 3, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 4, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 5, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 6, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 7, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 8, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 9, 0xB001},
+   /* EPCMPR (Event Processor Counter Compare Registers) */
+   {EPCMPR0 + EPCMPR_STRIDE * 0, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 1, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 2, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 3, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 4, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 5, 0x0020},
+   {EPCMPR0 + EPCMPR_STRIDE * 6, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 7, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 8, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 9, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 10, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 11, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 12, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 13, 0},
+   {EPCMPR0 + EPCMPR_STRIDE * 14, 0x00FF},
+   {EPCMPR0 + EPCMPR_STRIDE * 15, 0x00FF},
+   /* EPCCR (Event Processor Counter Control Registers) */
+   {EPCCR0 + EPCCR_STRIDE * 0, 0},
+   {EPCCR0 + EPCCR_STRIDE * 1, 0},
+   {EPCCR0 + EPCCR_STRIDE * 2, 0x9284},
+   {EPCCR0 + EPCCR_STRIDE * 3, 0},
+   {EPCCR0 + EPCCR_STRIDE * 4, 0x9284},
+   {EPCCR0 + EPCCR_STRIDE * 5, 0x9284},
+   {EPCCR0 + EPCCR_STRIDE * 6, 0},

[PATCH 4/4] powerpc: pm: support deep sleep feature on T104x

2015-07-31 Thread Chenhui Zhao
T104x has deep sleep feature, which can switch off most parts of
the SoC when it is in deep sleep mode. This way, it becomes more
energy-efficient.

The DDR controller will also be powered off in deep sleep. Therefore,
the last stage (the latter part of fsl_dp_enter_low) will run without DDR
access. This piece of code and related TLBs are prefetched in advance.

Due to the different initialization code between 32-bit and 64-bit, they
have separate resume entry and precedure.

The feature supports 32-bit and 64-bit kernel mode.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/include/asm/fsl_pm.h |  14 +
 arch/powerpc/kernel/fsl_booke_entry_mapping.S |  10 +
 arch/powerpc/kernel/head_64.S |   2 +-
 arch/powerpc/platforms/85xx/Makefile  |   1 +
 arch/powerpc/platforms/85xx/deepsleep.c   | 322 +++
 arch/powerpc/platforms/85xx/qoriq_pm.c|  81 +++-
 arch/powerpc/platforms/85xx/t104x_deepsleep.S | 570 ++
 7 files changed, 997 insertions(+), 3 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/deepsleep.c
 create mode 100644 arch/powerpc/platforms/85xx/t104x_deepsleep.S

diff --git a/arch/powerpc/include/asm/fsl_pm.h 
b/arch/powerpc/include/asm/fsl_pm.h
index 4b09f09..b44f484 100644
--- a/arch/powerpc/include/asm/fsl_pm.h
+++ b/arch/powerpc/include/asm/fsl_pm.h
@@ -12,6 +12,7 @@
 #define __PPC_FSL_PM_H
 #ifdef __KERNEL__
 
+#ifndef __ASSEMBLY__
 #define E500_PM_PH10   1
 #define E500_PM_PH15   2
 #define E500_PM_PH20   3
@@ -44,5 +45,18 @@ struct fsl_pm_ops {
 };
 
 extern const struct fsl_pm_ops *qoriq_pm_ops;
+
+extern int fsl_dp_iomap(void);
+extern void fsl_dp_iounmap(void);
+
+extern int fsl_enter_epu_deepsleep(void);
+extern void fsl_dp_enter_low(void __iomem *ccsr_base, void __iomem *dcsr_base,
+void __iomem *pld_base, int pld_flag);
+extern void fsl_booke_deep_sleep_resume(void);
+#endif /* __ASSEMBLY__ */
+
+#define T1040QDS_TETRA_FLAG1
+#define T104xRDB_CPLD_FLAG 2
+
 #endif /* __KERNEL__ */
 #endif /* __PPC_FSL_PM_H */
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S 
b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
index f22e7e4..32ec426f 100644
--- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S
+++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
@@ -170,6 +170,10 @@ skpinv:addir6,r6,1 /* 
Increment */
lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h
ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l
mtspr   SPRN_MAS2,r6
+#ifdef ENTRY_DEEPSLEEP_SETUP
+   LOAD_REG_IMMEDIATE(r8, MEMORY_START)
+   ori r8,r8,(MAS3_SX|MAS3_SW|MAS3_SR)
+#endif
mtspr   SPRN_MAS3,r8
tlbwe
 
@@ -212,12 +216,18 @@ next_tlb_setup:
#error You need to specify the mapping or not use this at all.
 #endif
 
+#ifdef ENTRY_DEEPSLEEP_SETUP
+   LOAD_REG_ADDR(r6, 2f)
+   mfmsr   r7
+   rlwinm  r7,r7,0,~(MSR_IS|MSR_DS)
+#else
lis r7,MSR_KERNEL@h
ori r7,r7,MSR_KERNEL@l
bl  1f  /* Find our address */
 1: mflrr9
rlwimi  r6,r9,0,20,31
addir6,r6,(2f - 1b)
+#endif
mtspr   SPRN_SRR0,r6
mtspr   SPRN_SRR1,r7
rfi /* start execution out of TLB1[0] entry 
*/
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index d48125d..b9eb02a 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -696,7 +696,7 @@ _GLOBAL(start_secondary_resume)
 /*
  * This subroutine clobbers r11 and r12
  */
-enable_64b_mode:
+_GLOBAL(enable_64b_mode)
mfmsr   r11 /* grab the current MSR */
 #ifdef CONFIG_PPC_BOOK3E
orisr11,r11,0x8000  /* CM bit set, we'll set ICM later */
diff --git a/arch/powerpc/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index 87fb847..a73d563 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -4,6 +4,7 @@
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_FSL_PMC)+= mpc85xx_pm_ops.o
 obj-$(CONFIG_FSL_QORIQ_PM)   += qoriq_pm.o sleep_fsm.o
+obj-$(CONFIG_FSL_QORIQ_PM)   += deepsleep.o t104x_deepsleep.o
 
 obj-y += common.o
 
diff --git a/arch/powerpc/platforms/85xx/deepsleep.c 
b/arch/powerpc/platforms/85xx/deepsleep.c
new file mode 100644
index 000..5de904d
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/deepsleep.c
@@ -0,0 +1,322 @@
+/*
+ * Support deep sleep feature for T104x
+ *
+ * Copyright 2015 Freescale Semiconductor Inc.
+ *
+ * Author: Chenhui Zhao 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#in

[PATCH 1/4] powerpc/85xx: support sleep feature on QorIQ SoCs with RCPM

2015-07-31 Thread Chenhui Zhao
In sleep mode, the clocks of e500 cores and unused IP blocks is
turned off. The IP blocks which are allowed to wake up the processor
are still running.

The sleep mode is equal to the Standby state in Linux. Use the
command to enter sleep mode:
  echo standby > /sys/power/state

Signed-off-by: Chenhui Zhao 
---
Note: This patch set is based on CPU hotplug patches.

 arch/powerpc/Kconfig   |  3 +-
 arch/powerpc/platforms/85xx/Kconfig|  5 +++
 arch/powerpc/platforms/85xx/Makefile   |  1 +
 arch/powerpc/platforms/85xx/qoriq_pm.c | 59 ++
 arch/powerpc/platforms/86xx/Kconfig|  1 +
 5 files changed, 67 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/qoriq_pm.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index dd9e252..57bbbfb 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -233,7 +233,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
@@ -753,7 +753,6 @@ config FSL_PCI
 
 config FSL_PMC
bool
-   default y
depends on SUSPEND && (PPC_85xx || PPC_86xx)
help
  Freescale MPC85xx/MPC86xx power management controller support
diff --git a/arch/powerpc/platforms/85xx/Kconfig 
b/arch/powerpc/platforms/85xx/Kconfig
index e626461..dff2ea6 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -9,6 +9,8 @@ menuconfig FSL_SOC_BOOKE
select SERIAL_8250_EXTENDED if SERIAL_8250
select SERIAL_8250_SHARE_IRQ if SERIAL_8250
select FSL_CORENET_RCPM if PPC_E500MC
+   select FSL_QORIQ_PM if SUSPEND && PPC_E500MC
+   select FSL_PMC if SUSPEND && !PPC_E500MC
default y
 
 if FSL_SOC_BOOKE
@@ -289,3 +291,6 @@ endif # FSL_SOC_BOOKE
 
 config TQM85xx
bool
+
+config FSL_QORIQ_PM
+   bool
diff --git a/arch/powerpc/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index 7bc86da..fdae28b 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)+= mpc85xx_pm_ops.o
+obj-$(CONFIG_FSL_QORIQ_PM)   += qoriq_pm.o
 
 obj-y += common.o
 
diff --git a/arch/powerpc/platforms/85xx/qoriq_pm.c 
b/arch/powerpc/platforms/85xx/qoriq_pm.c
new file mode 100644
index 000..27ec337
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/qoriq_pm.c
@@ -0,0 +1,59 @@
+/*
+ * Support Power Management feature
+ *
+ * Copyright 2014-2015 Freescale Semiconductor Inc.
+ *
+ * Author: Chenhui Zhao 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+static int qoriq_suspend_enter(suspend_state_t state)
+{
+   int ret = 0;
+
+   switch (state) {
+   case PM_SUSPEND_STANDBY:
+   cur_cpu_spec->cpu_down_flush();
+   ret = qoriq_pm_ops->plat_enter_sleep();
+   break;
+   default:
+   ret = -EINVAL;
+   }
+
+   return ret;
+}
+
+static int qoriq_suspend_valid(suspend_state_t state)
+{
+   unsigned int pm_modes;
+
+   pm_modes = qoriq_pm_ops->get_pm_modes();
+
+   if ((state == PM_SUSPEND_STANDBY) && (pm_modes & FSL_PM_SLEEP))
+   return 1;
+
+   return 0;
+}
+
+static const struct platform_suspend_ops qoriq_suspend_ops = {
+   .valid = qoriq_suspend_valid,
+   .enter = qoriq_suspend_enter,
+};
+
+static int __init qoriq_suspend_init(void)
+{
+   suspend_set_ops(&qoriq_suspend_ops);
+
+   return 0;
+}
+arch_initcall(qoriq_suspend_init);
diff --git a/arch/powerpc/platforms/86xx/Kconfig 
b/arch/powerpc/platforms/86xx/Kconfig
index 1afd1e4..09638e0 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -5,6 +5,7 @@ menuconfig PPC_86xx
select FSL_SOC
select ALTIVEC
select ARCH_WANT_OPTIONAL_GPIOLIB
+   select FSL_PMC if SUSPEND
help
  The Freescale E600 SoCs have 74xx cores.
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] powerpc/85xx: add sleep and deep sleep support

2015-07-24 Thread Chenhui Zhao
In sleep PM mode, the clocks of e500 core and unused IP blocks is
turned off. IP blocks which are allowed to wake up the processor
are still running.

Some Freescale chips like MPC8536 and P1022 has deep sleep PM mode
in addtion to the sleep PM mode.

While in deep sleep PM mode, additionally, the power supply is
removed from e500 core and most IP blocks. Only the blocks needed
to wake up the chip out of deep sleep are ON.

This patch supports 32-bit and 36-bit address space.

The sleep mode is equal to the Standby state in Linux. The deep sleep
mode is equal to the Suspend-to-RAM state of Linux Power Management.

Command to enter sleep mode.
  echo standby > /sys/power/state
Command to enter deep sleep mode.
  echo mem > /sys/power/state

Signed-off-by: Li Yang 
Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/include/asm/cacheflush.h   |   5 +
 arch/powerpc/platforms/85xx/Makefile|   3 +
 arch/powerpc/platforms/85xx/pmc_deepsleep.S | 645 
 arch/powerpc/sysdev/fsl_pmc.c   | 146 ++-
 arch/powerpc/sysdev/fsl_soc.h   |   5 +
 5 files changed, 785 insertions(+), 19 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/pmc_deepsleep.S

diff --git a/arch/powerpc/include/asm/cacheflush.h 
b/arch/powerpc/include/asm/cacheflush.h
index 30b35ff..9ec4c31 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -31,6 +31,11 @@ extern void flush_dcache_page(struct page *page);
 #define flush_dcache_mmap_unlock(mapping)  do { } while (0)
 
 extern void __flush_disable_L1(void);
+#ifdef CONFIG_FSL_BOOKE
+extern void flush_dcache_L1(void);
+#else
+#define flush_dcache_L1()  do { } while (0)
+#endif
 
 extern void flush_icache_range(unsigned long, unsigned long);
 extern void flush_icache_user_range(struct vm_area_struct *vma,
diff --git a/arch/powerpc/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index 1fe7fb9..d187253 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -2,6 +2,9 @@
 # Makefile for the PowerPC 85xx linux kernel.
 #
 obj-$(CONFIG_SMP) += smp.o
+ifneq ($(CONFIG_PPC_E500MC),y)
+obj-$(CONFIG_SUSPEND)  += pmc_deepsleep.o
+endif
 
 obj-y += common.o
 
diff --git a/arch/powerpc/platforms/85xx/pmc_deepsleep.S 
b/arch/powerpc/platforms/85xx/pmc_deepsleep.S
new file mode 100644
index 000..57fd4f4
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/pmc_deepsleep.S
@@ -0,0 +1,645 @@
+/*
+ * Enter and leave deep sleep/sleep state on MPC85xx
+ *
+ * Author: Scott Wood 
+ *
+ * Copyright 2006-2015 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define SS_TB  0x00
+#define SS_HID 0x08 /* 2 HIDs */
+#define SS_IAC 0x10 /* 2 IACs */
+#define SS_DAC 0x18 /* 2 DACs */
+#define SS_DBCR0x20 /* 3 DBCRs */
+#define SS_PID 0x2c /* 3 PIDs */
+#define SS_SPRG0x38 /* 8 SPRGs */
+#define SS_IVOR0x58 /* 20 interrupt vectors */
+#define SS_TCR 0xa8
+#define SS_BUCSR   0xac
+#define SS_L1CSR   0xb0 /* 2 L1CSRs */
+#define SS_MSR 0xb8
+#define SS_USPRG   0xbc
+#define SS_GPREG   0xc0 /* r12-r31 */
+#define SS_LR  0x110
+#define SS_CR  0x114
+#define SS_SP  0x118
+#define SS_CURRENT 0x11c
+#define SS_IVPR0x120
+#define SS_BPTR0x124
+
+
+#define STATE_SAVE_SIZE 0x128
+
+   .section .data
+   .align  5
+mpc85xx_sleep_save_area:
+   .space  STATE_SAVE_SIZE
+ccsrbase_low:
+   .long   0
+ccsrbase_high:
+   .long   0
+powmgtreq:
+   .long   0
+
+   .section .text
+
+   /* r3 = virtual address of L2 controller, WIMG = 01xx */
+flush_disable_L2:
+   /* It's a write-through cache, so only invalidation is needed. */
+   mbar
+   isync
+   lwz r4, 0(r3)
+   li  r5, 1
+   rlwimi  r4, r5, 30, 0xc000
+   stw r4, 0(r3)
+
+   /* Wait for the invalidate to finish */
+1: lwz r4, 0(r3)
+   andis.  r4, r4, 0x4000
+   bne 1b
+   mbar
+
+   blr
+
+   /* r3 = virtual address of L2 controller, WIMG = 01xx */
+invalidate_enable_L2:
+   mbar
+   isync
+   lwz r4, 0(r3)
+   li  r5, 3
+   rlwimi  r4, r5, 30, 0xc000
+   stw r4, 0(r3)
+
+   /* Wait for the invalidate to finish */
+1: lwz r4, 0(r3)
+   andis.  r4, r4, 0x4000
+   bne 1b
+   mbar
+
+   blr
+
+   /*
+* r3 = high word of physical address of CCSR
+* r4 = low word of physical address of CCSR
+* r5 = JOG or deep sl

[PATCH] powerpc/corenet: use the mixed mode of MPIC when enabling CPU hotplug

2015-07-22 Thread Chenhui Zhao
Core reset may cause issue if using the proxy mode of MPIC.
Use the mixed mode of MPIC if enabling CPU hotplug.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/platforms/85xx/corenet_generic.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c 
b/arch/powerpc/platforms/85xx/corenet_generic.c
index bd839dc..0119224 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -212,7 +212,15 @@ define_machine(corenet_generic) {
.pcibios_fixup_bus  = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb  = fsl_pcibios_fixup_phb,
 #endif
+/*
+ * Core reset may cause issue if using the proxy mode of MPIC.
+ * So, use the mixed mode of MPIC if enabling CPU hotplug.
+ */
+#ifdef CONFIG_HOTPLUG_CPU
+   .get_irq= mpic_get_irq,
+#else
.get_irq= mpic_get_coreint_irq,
+#endif
.restart= fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
.progress   = udbg_progress,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/4] powerpc/rcpm: add RCPM driver

2015-03-26 Thread Chenhui Zhao
There is a RCPM (Run Control/Power Management) in Freescale QorIQ
series processors. The device performs tasks associated with device
run control and power management.

The driver implements some features: mask/unmask irq, enter/exit low
power states, freeze time base, etc.

Signed-off-by: Chenhui Zhao 
---
 Documentation/devicetree/bindings/soc/fsl/rcpm.txt |  23 ++
 arch/powerpc/include/asm/fsl_guts.h| 105 ++
 arch/powerpc/include/asm/fsl_pm.h  |  49 +++
 arch/powerpc/platforms/85xx/Kconfig|   1 +
 arch/powerpc/sysdev/Kconfig|   5 +
 arch/powerpc/sysdev/Makefile   |   1 +
 arch/powerpc/sysdev/fsl_rcpm.c | 353 +
 7 files changed, 537 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/fsl/rcpm.txt
 create mode 100644 arch/powerpc/include/asm/fsl_pm.h
 create mode 100644 arch/powerpc/sysdev/fsl_rcpm.c

diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt 
b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
new file mode 100644
index 000..8c21b6c
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
@@ -0,0 +1,23 @@
+* Run Control and Power Management
+
+The RCPM performs all device-level tasks associated with device run control
+and power management.
+
+Required properites:
+  - reg : Offset and length of the register set of RCPM block.
+  - compatible : Specifies the compatibility list for the RCPM. The type
+should be string, such as "fsl,qoriq-rcpm-1.0", "fsl,qoriq-rcpm-2.0".
+
+Example:
+The RCPM node for T4240:
+   rcpm: global-utilities@e2000 {
+   compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0";
+   reg = <0xe2000 0x1000>;
+   };
+
+The RCPM node for P4080:
+   rcpm: global-utilities@e2000 {
+   compatible = "fsl,qoriq-rcpm-1.0";
+   reg = <0xe2000 0x1000>;
+   #sleep-cells = <1>;
+   };
diff --git a/arch/powerpc/include/asm/fsl_guts.h 
b/arch/powerpc/include/asm/fsl_guts.h
index 43b6bb1..96018ee 100644
--- a/arch/powerpc/include/asm/fsl_guts.h
+++ b/arch/powerpc/include/asm/fsl_guts.h
@@ -188,5 +188,110 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts 
__iomem *guts,
 
 #endif
 
+struct ccsr_rcpm_v1 {
+   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 Management Control&Status Register 
*/
+#define RCPM_POWMGTCSR_SLP 0x0002
+   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 Register */
+};
+
+struct ccsr_rcpm_v2 {
+   u8  res_00[12];
+   __be32  tph10sr0;   /* Thread PH10 Status Register */
+   u8  res_10[12];
+   __be32  tph10setr0; /* Thread PH10 Set Control Register */
+   u8  res_20[12];
+   __be32  tph10clrr0; /* Thread PH10 Clear Control Register */
+   u8  res_30[12];
+   __be32  tph10psr0;  /* Thread PH10 Previous Status Register */
+   u8  res_40[12];
+   __be32  twaitsr0;   /* Thread Wait Status Register */
+   u8  res_50[96];
+   __be32  pcph15sr;   /* Physical Core PH15 Status Register */
+   __be32  pcph15setr; /* Physical Core PH15 Set Control Register */
+   __be32  pcph15clrr; /* Physical Core PH15 Clear C

[PATCH 3/4] powerpc: support CPU hotplug for e500mc, e5500 and e6500

2015-03-26 Thread Chenhui Zhao
Implemented CPU hotplug on e500mc, e5500 and e6500, and support
multiple threads mode and 64-bits mode.

For e6500 with two threads, if one thread is online, it can
enable/disable the other thread in the same core. If two threads of
one core are offline, the core will enter the PH20 state (a low power
state). When the core is up again, Thread0 is up first, and it will be
bound with the present booting cpu. This way, all CPUs can hotplug
separately.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/Kconfig  |   2 +-
 arch/powerpc/include/asm/fsl_pm.h |   4 +
 arch/powerpc/include/asm/smp.h|   2 +
 arch/powerpc/kernel/head_64.S |  20 +++--
 arch/powerpc/kernel/smp.c |   5 ++
 arch/powerpc/platforms/85xx/smp.c | 182 +-
 arch/powerpc/sysdev/fsl_rcpm.c|  56 
 7 files changed, 220 insertions(+), 51 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 22b0940..9846c83 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -380,7 +380,7 @@ config SWIOTLB
 config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
depends on SMP && (PPC_PSERIES || \
-   PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
+   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/include/asm/fsl_pm.h 
b/arch/powerpc/include/asm/fsl_pm.h
index bbe6089..579f495 100644
--- a/arch/powerpc/include/asm/fsl_pm.h
+++ b/arch/powerpc/include/asm/fsl_pm.h
@@ -34,6 +34,10 @@ struct fsl_pm_ops {
void (*cpu_enter_state)(int cpu, int state);
/* exit the CPU from the specified state */
void (*cpu_exit_state)(int cpu, int state);
+   /* cpu up */
+   void (*cpu_up)(int cpu);
+   /* cpu die */
+   void (*cpu_die)(int cpu);
/* place the platform in the sleep state */
int (*plat_enter_sleep)(void);
/* freeze the time base */
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index d607df5..1e500ed 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -67,6 +67,7 @@ void generic_cpu_die(unsigned int cpu);
 void generic_set_cpu_dead(unsigned int cpu);
 void generic_set_cpu_up(unsigned int cpu);
 int generic_check_cpu_restart(unsigned int cpu);
+int generic_check_cpu_dead(unsigned int cpu);
 #endif
 
 #ifdef CONFIG_PPC64
@@ -198,6 +199,7 @@ extern void generic_secondary_thread_init(void);
 extern unsigned long __secondary_hold_spinloop;
 extern unsigned long __secondary_hold_acknowledge;
 extern char __secondary_hold;
+extern unsigned int __cur_boot_cpu;
 
 extern void __early_start(void);
 #endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index d48125d..ac89050 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -181,6 +181,10 @@ exception_marker:
 #endif
 
 #ifdef CONFIG_PPC_BOOK3E
+   .globl  __cur_boot_cpu
+__cur_boot_cpu:
+   .long  0x0
+   .align 3
 _GLOBAL(fsl_secondary_thread_init)
/* Enable branch prediction */
lis r3,BUCSR_INIT@h
@@ -189,16 +193,14 @@ _GLOBAL(fsl_secondary_thread_init)
isync
 
/*
-* Fix PIR to match the linear numbering in the device tree.
-*
-* On e6500, the reset value of PIR uses the low three bits for
-* the thread within a core, and the upper bits for the core
-* number.  There are two threads per core, so shift everything
-* but the low bit right by two bits so that the cpu numbering is
-* continuous.
+* The current thread has been in 64-bit mode,
+* see the value of TMRN_IMSR.
+* compute the address of __cur_boot_cpu
 */
-   mfspr   r3, SPRN_PIR
-   rlwimi  r3, r3, 30, 2, 30
+   bl  10f
+10:mflrr22
+   addir22,r22,(__cur_boot_cpu - 10b)
+   lwz r3,0(r22)
mtspr   SPRN_PIR, r3
 #endif
 
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index ec9ec20..2cca27a 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -454,6 +454,11 @@ int generic_check_cpu_restart(unsigned int cpu)
return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
 }
 
+int generic_check_cpu_dead(unsigned int cpu)
+{
+   return per_cpu(cpu_state, cpu) == CPU_DEAD;
+}
+
 static bool secondaries_inhibited(void)
 {
return kvm_hv_mode_active();
diff --git a/arch/powerpc/platforms/85xx/smp.c 
b/arch/powerpc/platforms/85xx/smp.c
index fba474f..f51441b 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -2,7 +2,7 @@
  * Author: Andy Fleming 
  *Kumar Gala 
  *
- * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc.
+ * Copyright 2006-2008, 2011-2012, 2015 Freescale Semiconductor

[PATCH 1/4] powerpc/cache: add cache flush operation for various e500

2015-03-26 Thread Chenhui Zhao
Various e500 core have different cache architecture, so they
need different cache flush operations. Therefore, add a callback
function cpu_flush_caches to the struct cpu_spec. The cache flush
operation for the specific kind of e500 is selected at init time.
The callback function will flush all caches inside the current cpu.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/include/asm/cacheflush.h |   2 -
 arch/powerpc/include/asm/cputable.h   |  11 +++
 arch/powerpc/kernel/asm-offsets.c |   3 +
 arch/powerpc/kernel/cpu_setup_fsl_booke.S | 114 +-
 arch/powerpc/kernel/cputable.c|   4 ++
 arch/powerpc/kernel/head_fsl_booke.S  |  74 ---
 arch/powerpc/platforms/85xx/smp.c |   3 +-
 7 files changed, 133 insertions(+), 78 deletions(-)

diff --git a/arch/powerpc/include/asm/cacheflush.h 
b/arch/powerpc/include/asm/cacheflush.h
index 30b35ff..729fde4 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -30,8 +30,6 @@ 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);
 extern void flush_icache_user_range(struct vm_area_struct *vma,
struct page *page, unsigned long addr,
diff --git a/arch/powerpc/include/asm/cputable.h 
b/arch/powerpc/include/asm/cputable.h
index 5cf5a6d..c776efe4 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -43,6 +43,13 @@ extern int machine_check_e500(struct pt_regs *regs);
 extern int machine_check_e200(struct pt_regs *regs);
 extern int machine_check_47x(struct pt_regs *regs);
 
+#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC)
+extern void __flush_caches_e500v2(void);
+extern void __flush_caches_e500mc(void);
+extern void __flush_caches_e5500(void);
+extern void __flush_caches_e6500(void);
+#endif
+
 /* NOTE WELL: Update identify_cpu() if fields are added or removed! */
 struct cpu_spec {
/* CPU is matched via (PVR & pvr_mask) == pvr_value */
@@ -59,6 +66,10 @@ struct cpu_spec {
unsigned inticache_bsize;
unsigned intdcache_bsize;
 
+#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC)
+   /* flush caches inside the current cpu */
+   void (*cpu_flush_caches)(void);
+#endif
/* number of performance monitor counters */
unsigned intnum_pmcs;
enum powerpc_pmc_type pmc_type;
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 4717859..9567930 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -372,6 +372,9 @@ int main(void)
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
+#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC)
+   DEFINE(CPU_FLUSH_CACHES, offsetof(struct cpu_spec, cpu_flush_caches));
+#endif
 
DEFINE(pbe_address, offsetof(struct pbe, address));
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S 
b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index dddba3e..c8c251f 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -1,7 +1,7 @@
 /*
  * This file contains low level CPU setup functions.
  * Kumar Gala 
- * Copyright 2009 Freescale Semiconductor, Inc.
+ * Copyright 2009, 2015 Freescale Semiconductor, Inc.
  *
  * Based on cpu_setup_6xx code by
  * Benjamin Herrenschmidt 
@@ -13,11 +13,13 @@
  *
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 _GLOBAL(__e500_icache_setup)
mfspr   r0, SPRN_L1CSR1
@@ -233,3 +235,113 @@ _GLOBAL(__setup_cpu_e5500)
mtlrr5
blr
 #endif
+
+/* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */
+_GLOBAL(flush_dcache_L1)
+   mfmsr   r10
+   wrteei  0
+
+   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

[PATCH 4/4] powerpc/85xx: support sleep feature on QorIQ SoCs with RCPM

2015-03-26 Thread Chenhui Zhao
In sleep mode, the clocks of e500 cores and unused IP blocks is
turned off. The IP blocks which are allowed to wake up the processor
are still running.

The sleep mode is equal to the Standby state in Linux. Use the
command to enter sleep mode:
  echo standby > /sys/power/state

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/Kconfig   |  3 +-
 arch/powerpc/platforms/85xx/Kconfig|  5 +++
 arch/powerpc/platforms/85xx/Makefile   |  1 +
 arch/powerpc/platforms/85xx/qoriq_pm.c | 59 ++
 arch/powerpc/platforms/86xx/Kconfig|  1 +
 5 files changed, 67 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/qoriq_pm.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9846c83..162eb53 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -233,7 +233,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
@@ -747,7 +747,6 @@ config FSL_PCI
 
 config FSL_PMC
bool
-   default y
depends on SUSPEND && (PPC_85xx || PPC_86xx)
help
  Freescale MPC85xx/MPC86xx power management controller support
diff --git a/arch/powerpc/platforms/85xx/Kconfig 
b/arch/powerpc/platforms/85xx/Kconfig
index ae1b8a2..b7c762e 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -9,6 +9,8 @@ menuconfig FSL_SOC_BOOKE
select SERIAL_8250_EXTENDED if SERIAL_8250
select SERIAL_8250_SHARE_IRQ if SERIAL_8250
select FSL_CORENET_RCPM if PPC_E500MC
+   select FSL_QORIQ_PM if SUSPEND && PPC_E500MC
+   select FSL_PMC if SUSPEND && !PPC_E500MC
default y
 
 if FSL_SOC_BOOKE
@@ -289,3 +291,6 @@ endif # FSL_SOC_BOOKE
 
 config TQM85xx
bool
+
+config FSL_QORIQ_PM
+   bool
diff --git a/arch/powerpc/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index 1fe7fb9..65dfb60 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_QORIQ_PM)   += qoriq_pm.o
 
 obj-y += common.o
 
diff --git a/arch/powerpc/platforms/85xx/qoriq_pm.c 
b/arch/powerpc/platforms/85xx/qoriq_pm.c
new file mode 100644
index 000..7594f08
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/qoriq_pm.c
@@ -0,0 +1,59 @@
+/*
+ * Support Power Management feature
+ *
+ * Copyright 2014-2015 Freescale Semiconductor Inc.
+ *
+ * Author: Chenhui Zhao 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+static int qoriq_suspend_enter(suspend_state_t state)
+{
+   int ret = 0;
+
+   switch (state) {
+   case PM_SUSPEND_STANDBY:
+   cur_cpu_spec->cpu_flush_caches();
+   ret = qoriq_pm_ops->plat_enter_sleep();
+   break;
+   default:
+   ret = -EINVAL;
+   }
+
+   return ret;
+}
+
+static int qoriq_suspend_valid(suspend_state_t state)
+{
+   unsigned int pm_modes;
+
+   pm_modes = qoriq_pm_ops->get_pm_modes();
+
+   if ((state == PM_SUSPEND_STANDBY) && (pm_modes & FSL_PM_SLEEP))
+   return 1;
+
+   return 0;
+}
+
+static const struct platform_suspend_ops qoriq_suspend_ops = {
+   .valid = qoriq_suspend_valid,
+   .enter = qoriq_suspend_enter,
+};
+
+static int __init qoriq_suspend_init(void)
+{
+   suspend_set_ops(&qoriq_suspend_ops);
+
+   return 0;
+}
+arch_initcall(qoriq_suspend_init);
diff --git a/arch/powerpc/platforms/86xx/Kconfig 
b/arch/powerpc/platforms/86xx/Kconfig
index 1afd1e4..09638e0 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -5,6 +5,7 @@ menuconfig PPC_86xx
select FSL_SOC
select ALTIVEC
select ARCH_WANT_OPTIONAL_GPIOLIB
+   select FSL_PMC if SUSPEND
help
  The Freescale E600 SoCs have 74xx cores.
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 4/4] arm: ls1021a: set wakeup devices dynamically for sleep/deep sleep

2015-01-30 Thread Chenhui Zhao
If a device works as a wakeup source, it will keep working in the period of
sleep/deep sleep. This patch sets the wakeup devices according to the wakeup
attribute of device.

Signed-off-by: Chenhui Zhao 
---
 arch/arm/boot/dts/ls1021a.dtsi |   2 +
 arch/arm/mach-imx/pm-ls1.c | 101 +
 2 files changed, 103 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 0c51ce0..64534c0 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -136,6 +136,7 @@
sdhci,auto-cmd12;
big-endian;
bus-width = <4>;
+   sleep = <&rcpm 0x0080 0x0>;
status = "disabled";
};
 
@@ -289,6 +290,7 @@
interrupts = ;
clocks = <&sysclk>;
clock-names = "ipg";
+   sleep = <&rcpm 0x0 0x4000>;
status = "disabled";
};
 
diff --git a/arch/arm/mach-imx/pm-ls1.c b/arch/arm/mach-imx/pm-ls1.c
index 4f9ca80..b11fcb2 100644
--- a/arch/arm/mach-imx/pm-ls1.c
+++ b/arch/arm/mach-imx/pm-ls1.c
@@ -35,6 +35,13 @@
 #define CCSR_SCFG_DPSLPCR  0
 #define CCSR_SCFG_DPSLPCR_VAL  0x1
 #define CCSR_SCFG_PMCINTECR0x160
+#define CCSR_SCFG_PMCINTECR_LPUART 0x4000
+#define CCSR_SCFG_PMCINTECR_FTM0x2000
+#define CCSR_SCFG_PMCINTECR_GPIO   0x1000
+#define CCSR_SCFG_PMCINTECR_IRQ0   0x0800
+#define CCSR_SCFG_PMCINTECR_IRQ1   0x0400
+#define CCSR_SCFG_PMCINTECR_ETSECRXG0  0x0080
+#define CCSR_SCFG_PMCINTECR_ETSECRXG1  0x0040
 #define CCSR_SCFG_PMCINTLECR   0x164
 #define CCSR_SCFG_PMCINTSR 0x168
 #define CCSR_SCFG_SPARECR2 0x504
@@ -50,7 +57,11 @@
 #define CCSR_RCPM_CLPCL10SETR  0x1c4
 #define CCSR_RCPM_CLPCL10SETR_C0   0x1
 #define CCSR_RCPM_IPPDEXPCR0   0x140
+#define CCSR_RCPM_IPPDEXPCR0_ETSEC 0x8000
+#define CCSR_RCPM_IPPDEXPCR0_GPIO  0x0040
 #define CCSR_RCPM_IPPDEXPCR1   0x144
+#define CCSR_RCPM_IPPDEXPCR1_LPUART0x4000
+#define CCSR_RCPM_IPPDEXPCR1_FLEXTIMER 0x2000
 
 #define QIXIS_CTL_SYS  0x5
 #define QIXIS_CTL_SYS_EVTSW_MASK   0x0c
@@ -64,6 +75,10 @@
 /* use the last page of SRAM */
 #define SRAM_CODE_BASE_PHY (OCRAM_BASE + OCRAM_SIZE - PAGE_SIZE)
 
+#define SLEEP_ARRAY_SIZE   3
+
+static u32 ippdexpcr0, ippdexpcr1;
+
 struct ls1_pm_baseaddr {
void __iomem *rcpm;
void __iomem *epu;
@@ -242,6 +257,49 @@ static void ls1_board_resume(void)
iowrite8(tmp, ls1_pm_base.fpga + QIXIS_CTL_SYS);
 }
 
+static void ls1_setup_pmc_int(void)
+{
+   u32 pmcintecr;
+
+   pmcintecr = 0;
+   if (ippdexpcr0 & CCSR_RCPM_IPPDEXPCR0_ETSEC)
+   pmcintecr |= CCSR_SCFG_PMCINTECR_ETSECRXG0 |
+   CCSR_SCFG_PMCINTECR_ETSECRXG1;
+
+   if (ippdexpcr0 & CCSR_RCPM_IPPDEXPCR0_GPIO)
+   pmcintecr |= CCSR_SCFG_PMCINTECR_GPIO;
+
+   if (ippdexpcr1 & CCSR_RCPM_IPPDEXPCR1_LPUART)
+   pmcintecr |= CCSR_SCFG_PMCINTECR_LPUART;
+
+   if (ippdexpcr1 & CCSR_RCPM_IPPDEXPCR1_FLEXTIMER)
+   pmcintecr |= CCSR_SCFG_PMCINTECR_FTM;
+
+   /* always set external IRQ pins as wakeup source */
+   pmcintecr |= CCSR_SCFG_PMCINTECR_IRQ0 | CCSR_SCFG_PMCINTECR_IRQ1;
+
+   /* enable wakeup interrupt during deep sleep */
+   iowrite32be(pmcintecr, ls1_pm_base.scfg + CCSR_SCFG_PMCINTECR);
+   iowrite32be(0, ls1_pm_base.scfg + CCSR_SCFG_PMCINTLECR);
+   /* clear PMC interrupt status */
+   iowrite32be(0x, ls1_pm_base.scfg + CCSR_SCFG_PMCINTSR);
+}
+
+static void ls1_clear_pmc_int(void)
+{
+   /* disable wakeup interrupt during deep sleep */
+   iowrite32be(0, ls1_pm_base.scfg + CCSR_SCFG_PMCINTECR);
+   /* clear PMC interrupt status */
+   iowrite32be(0x, ls1_pm_base.scfg + CCSR_SCFG_PMCINTSR);
+}
+
+/* set IP powerdown exception, make them work during sleep/deep sleep */
+static void ls1_set_powerdown(void)
+{
+   iowrite32be(ippdexpcr0, ls1_pm_base.rcpm + CCSR_RCPM_IPPDEXPCR0);
+   iowrite32be(ippdexpcr1, ls1_pm_base.rcpm + CCSR_RCPM_IPPDEXPCR1);
+}
+
 static void ls1_enter_deepsleep(void)
 {
/* save DDR data */
@@ -265,8 +323,12 @@ static void ls1_enter_deepsleep(void)
/* copy the last stage code to sram */
ls1_copy_sram_code();
 
+   ls1_setup_pmc_int();
+
cpu_suspend(SRAM_CODE_BASE_PHY, ls1_start_deepsleep);
 
+   ls1_clear_pmc_int();
+
/* disable Warm Device Reset */
ls1_clrsetbits_be32(ls1_pm_base.scfg + CCSR_SCFG_DPSLPCR,
CCSR_SCFG_DPSLPCR_VAL, 0);
@@ -274,10 +336,45 @@ static void ls1_enter_deepsleep(void)
ls1

[PATCH 1/4] fsl: add EPU FSM configuration for deep sleep

2015-01-30 Thread Chenhui Zhao
T104x, T1024 and LS1021 of Freescale have a Finite State Machine (FSM)
to control the hardware precedure in deep sleep. Software will start
the FSM to enter deep sleep after finishing prepare work.
Then, when receiving a wakeup event, the FSM will restore the SoC to
work.

This driver configures and clears the FSM registers for deep sleep. Note
that the sequence of clearing the FSM registers does matter, should follow
the sequence mentioned in the reference manual.

Signed-off-by: Chenhui Zhao 
---
 drivers/platform/Kconfig |   2 +
 drivers/platform/Makefile|   1 +
 drivers/platform/fsl/Kconfig |  11 ++
 drivers/platform/fsl/Makefile|   5 +
 drivers/platform/fsl/sleep_fsm.c | 263 +++
 drivers/platform/fsl/sleep_fsm.h | 104 
 6 files changed, 386 insertions(+)
 create mode 100644 drivers/platform/fsl/Kconfig
 create mode 100644 drivers/platform/fsl/Makefile
 create mode 100644 drivers/platform/fsl/sleep_fsm.c
 create mode 100644 drivers/platform/fsl/sleep_fsm.h

diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 09fde58..85e3c95 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -6,3 +6,5 @@ source "drivers/platform/goldfish/Kconfig"
 endif
 
 source "drivers/platform/chrome/Kconfig"
+
+source "drivers/platform/fsl/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index 3656b7b..37c6f72 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_X86)   += x86/
 obj-$(CONFIG_OLPC) += olpc/
 obj-$(CONFIG_GOLDFISH) += goldfish/
 obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
+obj-$(CONFIG_FSL_SOC)  += fsl/
diff --git a/drivers/platform/fsl/Kconfig b/drivers/platform/fsl/Kconfig
new file mode 100644
index 000..a1ea46e
--- /dev/null
+++ b/drivers/platform/fsl/Kconfig
@@ -0,0 +1,11 @@
+#
+# Freescale Specific Power Management Drivers
+#
+
+config FSL_SLEEP_FSM
+   bool
+   help
+ This driver configures a hardware FSM (Finite State Machine) used in 
deep sleep.
+ The FSM finishes clean-ups at the last stage of entering deep sleep, 
and also
+ wakes up system when a wake up event happens. So far, T104x, T1024 
and LS1021
+ need this.
diff --git a/drivers/platform/fsl/Makefile b/drivers/platform/fsl/Makefile
new file mode 100644
index 000..d99ca0e
--- /dev/null
+++ b/drivers/platform/fsl/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/fsl
+# Freescale Specific Power Management Drivers
+#
+obj-$(CONFIG_FSL_SLEEP_FSM)+= sleep_fsm.o
diff --git a/drivers/platform/fsl/sleep_fsm.c b/drivers/platform/fsl/sleep_fsm.c
new file mode 100644
index 000..0a0480a
--- /dev/null
+++ b/drivers/platform/fsl/sleep_fsm.c
@@ -0,0 +1,263 @@
+/*
+ * Freescale deep sleep FSM (finite-state machine) configuration
+ *
+ * Copyright 2014-2015 Freescale Semiconductor Inc.
+ *
+ * Author: Hongbo Zhang 
+ * Chenhui Zhao 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#include "sleep_fsm.h"
+/*
+ * These values are from chip's reference manual. For example,
+ * the values for T1040 can be found in "8.4.3.8 Programming
+ * supporting deep sleep mode" of Chapter 8 "Run Control and
+ * Power Management (RCPM)".
+ * The default value can be applied to T104x, T1024 and LS1021.
+ */
+struct fsm_reg_vals epu_default_val[] = {
+   /* EPGCR (Event Processor Global Control Register) */
+   {EPGCR, 0},
+   /* EPECR (Event Processor Event Control Registers) */
+   {EPECR0 + EPECR_STRIDE * 0, 0},
+   {EPECR0 + EPECR_STRIDE * 1, 0},
+   {EPECR0 + EPECR_STRIDE * 2, 0xF0004004},
+   {EPECR0 + EPECR_STRIDE * 3, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 4, 0x2084},
+   {EPECR0 + EPECR_STRIDE * 5, 0x0804},
+   {EPECR0 + EPECR_STRIDE * 6, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 7, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 8, 0x6084},
+   {EPECR0 + EPECR_STRIDE * 9, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 10, 0x4284},
+   {EPECR0 + EPECR_STRIDE * 11, 0x9084},
+   {EPECR0 + EPECR_STRIDE * 12, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 13, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 14, 0x0284},
+   {EPECR0 + EPECR_STRIDE * 15, 0x0004},
+   /*
+* EPEVTCR (Event Processor EVT Pin Control Registers)
+* SCU8 triger EVT2, and SCU11 triger EVT9
+*/
+   {EPEVTCR0 + EPEVTCR_STRIDE * 0, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 1, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 2, 0x8001},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 3, 

[PATCH 3/4] arm: ls1021a: add deep sleep support

2015-01-30 Thread Chenhui Zhao
The ls1021a SoC supports deep sleep feature that can switch off most
parts of the SoC when it is in deep sleep state.

The DDR controller will also be powered off in deep sleep. Therefore,
copy the last stage code to enter deep sleep to SRAM and run it
with disabling MMU and caches.

Signed-off-by: Chenhui Zhao 
---
 arch/arm/mach-imx/Kconfig |   1 +
 arch/arm/mach-imx/Makefile|   2 +
 arch/arm/mach-imx/pm-ls1.c| 374 ++
 arch/arm/mach-imx/sleep-ls1.S | 137 
 arch/arm/mach-imx/sleep-ls1.h |  19 +++
 5 files changed, 533 insertions(+)
 create mode 100644 arch/arm/mach-imx/pm-ls1.c
 create mode 100644 arch/arm/mach-imx/sleep-ls1.S
 create mode 100644 arch/arm/mach-imx/sleep-ls1.h

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index e8627e0..c10acff 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -664,6 +664,7 @@ config SOC_LS1021A
select HAVE_ARM_ARCH_TIMER
select PCI_DOMAINS if PCI
select ZONE_DMA if ARM_LPAE
+   select FSL_SLEEP_FSM if PM
 
help
  This enable support for Freescale LS1021A processor.
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index f5ac685..358adf4 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -101,6 +101,8 @@ obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o mach-imx6sx.o
 ifeq ($(CONFIG_SUSPEND),y)
 AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
+AFLAGS_sleep-ls1.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_LS1021A) += pm-ls1.o sleep-ls1.o
 endif
 obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
 
diff --git a/arch/arm/mach-imx/pm-ls1.c b/arch/arm/mach-imx/pm-ls1.c
new file mode 100644
index 000..4f9ca80
--- /dev/null
+++ b/arch/arm/mach-imx/pm-ls1.c
@@ -0,0 +1,374 @@
+/*
+ * Support deep sleep feature for LS1
+ *
+ * Copyright 2014-2015 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "common.h"
+#include "sleep-ls1.h"
+
+#define FSL_SLEEP  0x1
+#define FSL_DEEP_SLEEP 0x2
+
+#define DCSR_EPU_EPSMCR15  0x278
+#define DCSR_EPU_EPECR00x300
+#define DCSR_RCPM_CG1CR0   0x31c
+#define DCSR_RCPM_CSTTACR0 0xb00
+
+#define CCSR_SCFG_DPSLPCR  0
+#define CCSR_SCFG_DPSLPCR_VAL  0x1
+#define CCSR_SCFG_PMCINTECR0x160
+#define CCSR_SCFG_PMCINTLECR   0x164
+#define CCSR_SCFG_PMCINTSR 0x168
+#define CCSR_SCFG_SPARECR2 0x504
+#define CCSR_SCFG_SPARECR3 0x508
+
+#define CCSR_DCFG_CRSTSR   0x400
+#define CCSR_DCFG_CRSTSR_VAL   0x0008
+
+#define CCSR_RCPM_POWMGTCSR0x130
+#define CCSR_RCPM_POWMGTCSR_LPM20_REQ  0x0010
+#define CCSR_RCPM_POWMGTCSR_LPM20_ST   0x0200
+#define CCSR_RCPM_POWMGTCSR_P_LPM20_ST 0x0100
+#define CCSR_RCPM_CLPCL10SETR  0x1c4
+#define CCSR_RCPM_CLPCL10SETR_C0   0x1
+#define CCSR_RCPM_IPPDEXPCR0   0x140
+#define CCSR_RCPM_IPPDEXPCR1   0x144
+
+#define QIXIS_CTL_SYS  0x5
+#define QIXIS_CTL_SYS_EVTSW_MASK   0x0c
+#define QIXIS_CTL_SYS_EVTSW_IRQ0x04
+
+#define QIXIS_PWR_CTL2 0x21
+#define QIXIS_PWR_CTL2_PCTL0x2
+
+#define OCRAM_BASE 0x1000
+#define OCRAM_SIZE 0x1 /* 64K */
+/* use the last page of SRAM */
+#define SRAM_CODE_BASE_PHY (OCRAM_BASE + OCRAM_SIZE - PAGE_SIZE)
+
+struct ls1_pm_baseaddr {
+   void __iomem *rcpm;
+   void __iomem *epu;
+   void __iomem *dcsr_rcpm1;
+   void __iomem *scfg;
+   void __iomem *dcfg;
+   void __iomem *fpga;
+   void __iomem *sram;
+};
+
+/* 128 bytes buffer for restoring data broke by DDR training initialization */
+#define DDR_BUF_SIZE   128
+static u8 ddr_buff[DDR_BUF_SIZE] __aligned(64);
+static struct ls1_pm_baseaddr ls1_pm_base;
+/* supported sleep modes by the present platform */
+static unsigned int sleep_modes;
+static suspend_state_t ls1_pm_state;
+
+static inline void ls1_clrsetbits_be32(void __iomem *addr, u32 mask, u32 val)
+{
+   u32 tmp;
+
+   tmp = ioread32be(addr);
+   tmp = (tmp & ~mask) | val;
+   iowrite32be(tmp, addr);
+}
+
+static void __iomem *of_iomap_str(const char *compatible)
+{
+   struct device_node *np;
+   void __iomem *base;
+
+   np = of_find_compatible_node(NULL, NULL, compatible);
+   if (!np) {
+   pr_err("%s: can not find the compatible \"%s\"\n",
+   __func__, compatible);
+   return NULL;
+   }
+
+   base = of_iomap(np, 0);
+   of_node_put(np);
+ 

[PATCH 2/4] arm: ls1021a: add dts nodes required by deep sleep

2015-01-30 Thread Chenhui Zhao
Add RCPM and DCSR nodes.

Signed-off-by: Chenhui Zhao 
---
 arch/arm/boot/dts/ls1021a-qds.dts |   6 +-
 arch/arm/boot/dts/ls1021a.dtsi| 117 ++
 2 files changed, 122 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/ls1021a-qds.dts 
b/arch/arm/boot/dts/ls1021a-qds.dts
index 9c5e16b..6903f43 100644
--- a/arch/arm/boot/dts/ls1021a-qds.dts
+++ b/arch/arm/boot/dts/ls1021a-qds.dts
@@ -157,7 +157,7 @@
fpga: board-control@3,0 {
#address-cells = <1>;
#size-cells = <1>;
-   compatible = "simple-bus";
+   compatible = "fsl,ls1021aqds-fpga", "simple-bus";
reg = <0x3 0x0 0x100>;
bank-width = <1>;
device-width = <1>;
@@ -238,3 +238,7 @@
 &uart1 {
status = "okay";
 };
+
+&rcpm {
+   fsl,deep-sleep;
+};
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..0c51ce0 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -183,6 +183,11 @@
};
};
 
+   rcpm: rcpm@1ee2000 {
+   compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1";
+   reg = <0x0 0x1ee2000 0x0 0x1>;
+   };
+
dspi0: dspi@210 {
compatible = "fsl,vf610-dspi";
#address-cells = <1>;
@@ -406,4 +411,116 @@
dr_mode = "host";
};
};
+
+   dcsr {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   compatible = "fsl,dcsr", "simple-bus";
+   ranges = <0x0 0x0 0x2000 0x100>;
+
+   dcsr-epu@0 {
+   compatible = "fsl,ls1021a-dcsr-epu";
+   reg = <0x0 0x1>;
+   };
+
+   dcsr-gdi@10 {
+   compatible = "fsl,ls1021a-dcsr-gdi";
+   reg = <0x10 0x1>;
+   };
+
+   dcsr-dddi@12 {
+   compatible = "fsl,ls1021a-dcsr-dddi";
+   reg = <0x12 0x1>;
+   };
+
+   dcsr-dcfg@22 {
+   compatible = "fsl,ls1021a-dcsr-dcfg";
+   reg = <0x22 0x1000>;
+   };
+
+   dcsr-clock@221000 {
+   compatible = "fsl,ls1021a-dcsr-clock";
+   reg = <0x221000 0x1000>;
+   };
+
+   dcsr-rcpm@222000 {
+   compatible = "fsl,ls1021a-dcsr-rcpm";
+   reg = <0x222000 0x1000 0x223000 0x1000>;
+   };
+
+   dcsr-ccp@225000 {
+   compatible = "fsl,ls1021a-dcsr-ccp";
+   reg = <0x225000 0x1000>;
+   };
+
+   dcsr-fusectrl@226000 {
+   compatible = "fsl,ls1021a-dcsr-fusectrl";
+   reg = <0x226000 0x1000>;
+   };
+
+   dcsr-dap@30 {
+   compatible = "fsl,ls1021a-dcsr-dap";
+   reg = <0x30 0x1>;
+   };
+
+   dcsr-cstf@35 {
+   compatible = "fsl,ls1021a-dcsr-cstf";
+   reg = <0x35 0x1000 0x3a7000 0x1000>;
+   };
+
+   dcsr-a7rom@36 {
+   compatible = "fsl,ls1021a-dcsr-a7rom";
+   reg = <0x36 0x1>;
+   };
+
+   dcsr-a7cpu@37 {
+   compatible = "fsl,ls1021a-dcsr-a7cpu";
+   reg = <0x37 0x8000>;
+   };
+
+   dcsr-a7cti@378000 {
+   compatible = "fsl,ls1021a-dcsr-a7cti";
+   reg = <0x378000 0x4000>;
+   };
+
+   dcsr-etm@37c000 {
+   compatible = "fsl,ls1021a-dcsr-etm";
+   reg = <0x37c000 0x1000 0x37d000 0x3000>;
+   };
+
+   dcsr-hugorom@3a {
+   compatible = "fsl,ls1021a-dcsr-hugorom";
+   reg = <0x3a 0x1000>;
+   };
+
+   dcsr-etf@3a1000 {
+   compatible = "fsl,ls1021a-dcsr-etf";
+   reg = <0x3a1000 0x1000 0x3a2000 0x1000>;
+   };
+
+   dcsr-etr@3a3000 {
+   compatible

[PATCH v2 1/2] pm: add FSM configuration for deep sleep

2014-10-22 Thread Chenhui Zhao
For some Freescale's SoCs which support deep sleep, such as T1040,
LS1021, software will start a Finite State Machine (FSM) to control
the hardware precedure to enter deep sleep and return from it.

This patch configures parameters of the FSM preparing for deep sleep.

Signed-off-by: Chenhui Zhao 
---
Changes for v2:
 * use iowrite32be()

 drivers/platform/Kconfig |1 +
 drivers/platform/Makefile|1 +
 drivers/platform/fsl/Kconfig |   10 ++
 drivers/platform/fsl/Makefile|5 +
 drivers/platform/fsl/sleep_fsm.c |  269 ++
 drivers/platform/fsl/sleep_fsm.h |  106 +++
 6 files changed, 392 insertions(+), 0 deletions(-)
 create mode 100644 drivers/platform/fsl/Kconfig
 create mode 100644 drivers/platform/fsl/Makefile
 create mode 100644 drivers/platform/fsl/sleep_fsm.c
 create mode 100644 drivers/platform/fsl/sleep_fsm.h

diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 69616ae..54ada25 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -5,3 +5,4 @@ if GOLDFISH
 source "drivers/platform/goldfish/Kconfig"
 endif
 
+source "drivers/platform/fsl/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index 8a44a4c..d0cce95 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_X86)  += x86/
 obj-$(CONFIG_OLPC) += olpc/
 obj-$(CONFIG_GOLDFISH) += goldfish/
+obj-$(CONFIG_FSL_SOC)  += fsl/
diff --git a/drivers/platform/fsl/Kconfig b/drivers/platform/fsl/Kconfig
new file mode 100644
index 000..72ed053
--- /dev/null
+++ b/drivers/platform/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale Specific Power Management Drivers
+#
+
+config FSL_SLEEP_FSM
+   bool
+   help
+ This driver configures a hardware FSM (Finite State Machine) for deep 
sleep.
+ The FSM is used to finish clean-ups at the last stage of system 
entering deep
+ sleep, and also wakes up system when a wake up event happens.
diff --git a/drivers/platform/fsl/Makefile b/drivers/platform/fsl/Makefile
new file mode 100644
index 000..d99ca0e
--- /dev/null
+++ b/drivers/platform/fsl/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/fsl
+# Freescale Specific Power Management Drivers
+#
+obj-$(CONFIG_FSL_SLEEP_FSM)+= sleep_fsm.o
diff --git a/drivers/platform/fsl/sleep_fsm.c b/drivers/platform/fsl/sleep_fsm.c
new file mode 100644
index 000..32616ad
--- /dev/null
+++ b/drivers/platform/fsl/sleep_fsm.c
@@ -0,0 +1,269 @@
+/*
+ * Freescale deep sleep FSM (finite-state machine) configuration
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#include "sleep_fsm.h"
+/*
+ * These values are from chip's reference manual. For example,
+ * the values for T1040 can be found in "8.4.3.8 Programming
+ * supporting deep sleep mode" of Chapter 8 "Run Control and
+ * Power Management (RCPM)".
+ * The default value can be applied to T104x, LS1021.
+ */
+struct fsm_reg_vals epu_default_val[] = {
+   /* EPGCR (Event Processor Global Control Register) */
+   {EPGCR, 0},
+   /* EPECR (Event Processor Event Control Registers) */
+   {EPECR0 + EPECR_STRIDE * 0, 0},
+   {EPECR0 + EPECR_STRIDE * 1, 0},
+   {EPECR0 + EPECR_STRIDE * 2, 0xF0004004},
+   {EPECR0 + EPECR_STRIDE * 3, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 4, 0x2084},
+   {EPECR0 + EPECR_STRIDE * 5, 0x0804},
+   {EPECR0 + EPECR_STRIDE * 6, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 7, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 8, 0x6084},
+   {EPECR0 + EPECR_STRIDE * 9, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 10, 0x4284},
+   {EPECR0 + EPECR_STRIDE * 11, 0x9084},
+   {EPECR0 + EPECR_STRIDE * 12, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 13, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 14, 0x0284},
+   {EPECR0 + EPECR_STRIDE * 15, 0x0004},
+   /*
+* EPEVTCR (Event Processor EVT Pin Control Registers)
+* SCU8 triger EVT2, and SCU11 triger EVT9
+*/
+   {EPEVTCR0 + EPEVTCR_STRIDE * 0, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 1, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 2, 0x8001},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 3, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 4, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 5, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 6, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 7, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 8, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 9, 0xB001},
+   /* EPCMPR (Event Processor Counter C

[PATCH v2 2/2] arm: pm: add deep sleep support for LS1

2014-10-22 Thread Chenhui Zhao
LS1 supports deep sleep feature that can switch off most parts of
the SoC when it is in deep sleep state.

The DDR controller will also be powered off in deep sleep. Therefore,
copy the last stage code to enter deep sleep to SRAM and run it
with disabling MMU and caches.

Signed-off-by: Chenhui Zhao 
---
Changes for v2:
 * use identity mapping to smooth the process of disabling MMU
 * change the value of registers

 arch/arm/mach-imx/Kconfig |1 +
 arch/arm/mach-imx/Makefile|1 +
 arch/arm/mach-imx/pm-ls1.c|  341 +
 arch/arm/mach-imx/sleep-ls1.S |  132 
 4 files changed, 475 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-imx/pm-ls1.c
 create mode 100644 arch/arm/mach-imx/sleep-ls1.S

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index b85534c..716bb1b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -866,6 +866,7 @@ config SOC_LS1021A
select HAVE_SMP
select ARCH_LAYERSCAPE
select ZONE_DMA if ARM_LPAE
+   select FSL_SLEEP_FSM if PM
 
help
  This enable support for Freescale Layerscape LS1021A  processor.
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 41b8044..9931528 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
 
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
+obj-$(CONFIG_SOC_LS1021A) += pm-ls1.o sleep-ls1.o
 endif
 
 # i.MX5 based machines
diff --git a/arch/arm/mach-imx/pm-ls1.c b/arch/arm/mach-imx/pm-ls1.c
new file mode 100644
index 000..8fd7aee
--- /dev/null
+++ b/arch/arm/mach-imx/pm-ls1.c
@@ -0,0 +1,341 @@
+/*
+ * Support deep sleep feature for LS1
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "common.h"
+
+#define FSL_SLEEP  0x1
+#define FSL_DEEP_SLEEP 0x2
+
+#define DCSR_EPU_EPSMCR15  0x278
+#define DCSR_EPU_EPECR00x300
+#define DCSR_RCPM_CG1CR0   0x31c
+#define DCSR_RCPM_CSTTACR0 0xb00
+
+#define CCSR_SCFG_DPSLPCR  0
+#define CCSR_SCFG_DPSLPCR_VAL  0x1
+#define CCSR_SCFG_SPARECR2 0x504
+#define CCSR_SCFG_SPARECR3 0x508
+
+#define CCSR_DCFG_CRSTSR   0x400
+#define CCSR_DCFG_CRSTSR_VAL   0x0008
+
+#define CCSR_RCPM_POWMGTCSR0x130
+#define CCSR_RCPM_POWMGTCSR_LPM20_REQ  0x0010
+#define CCSR_RCPM_POWMGTCSR_LPM20_ST   0x0200
+#define CCSR_RCPM_POWMGTCSR_P_LPM20_ST 0x0100
+#define CCSR_RCPM_CLPCL10SETR  0x1c4
+#define CCSR_RCPM_CLPCL10SETR_C0   0x1
+
+#define OCRAM_BASE 0x1000
+#define OCRAM_SIZE 0x1 /* 64K */
+/* use the last page of SRAM */
+#define SRAM_CODE_BASE_PHY (OCRAM_BASE + OCRAM_SIZE - PAGE_SIZE)
+
+struct ls1_pm_baseaddr {
+   void __iomem *epu;
+   void __iomem *dcsr_rcpm1;
+   void __iomem *dcsr_rcpm2;
+   void __iomem *rcpm;
+   void __iomem *scfg;
+   void __iomem *dcfg;
+   void __iomem *fpga;
+   void __iomem *sram;
+};
+
+/* 128 bytes buffer for restoring data broke by DDR training initialization */
+#define DDR_BUF_SIZE   128
+static u8 ddr_buff[DDR_BUF_SIZE] __aligned(64);
+static struct ls1_pm_baseaddr ls1_pm_base;
+/* supported sleep modes by the present platform */
+static unsigned int sleep_modes;
+
+extern void ls1_do_deepsleep(unsigned long addr);
+extern void ls1_start_fsm(void);
+extern void ls1_deepsleep_resume(void);
+extern void ls1021a_set_secondary_entry(void);
+extern int ls1_sram_code_size;
+extern void fsl_epu_setup_default(void __iomem *epu_base);
+
+static void ls1_pm_iomap(void)
+{
+   struct device_node *np;
+   void *base;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcsr-epu");
+   base = of_iomap(np, 0);
+   BUG_ON(!base);
+   ls1_pm_base.epu = base;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcsr-rcpm");
+   base = of_iomap(np, 0);
+   BUG_ON(!base);
+   ls1_pm_base.dcsr_rcpm1 = base;
+   base = of_iomap(np, 1);
+   BUG_ON(!base);
+   ls1_pm_base.dcsr_rcpm2 = base;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-scfg");
+   base = of_iomap(np, 0);
+   BUG_ON(!base);
+   ls1_pm_base.scfg = base;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg");
+   base = of_iomap(np, 0);
+   BUG_ON(!base);
+   ls1_pm_base.dcfg = base;
+
+   np = of_find_compatible_node(NULL, NULL, 

Re: [PATCH 3/3] arm: pm: add deep sleep support for LS1

2014-09-29 Thread Chenhui Zhao
On Sun, Sep 28, 2014 at 03:26:33PM +0100, Russell King - ARM Linux wrote:
> On Sun, Sep 28, 2014 at 07:06:40PM +0800, Chenhui Zhao wrote:
> > On Fri, Sep 26, 2014 at 01:14:27PM +0100, Russell King - ARM Linux wrote:
> > > On Fri, Sep 26, 2014 at 07:25:03PM +0800, Chenhui Zhao wrote:
> > > > +/*
> > > > + * r0: the physical entry address of SRAM code
> > > > + *
> > > > + */
> > > > +ENTRY(ls1_do_deepsleep)
> > > > +   mov r13, r0
> > > > +
> > > > +   /* flush cache */
> > > > +   bl  v7_flush_dcache_all
> > > 
> > > Please explain the purpose of this call via a comment in the code.
> > > 
> > > The generic code will have saved the CPU state, and will have called
> > > flush_cache_louis() to flush the caches to the point of unification.
> > > 
> > > The only data which will have been loaded into the cache between that
> > > point is the stack for the return from __cpu_suspend_save, and
> > > speculative prefetches.
> > > 
> > > So, the only reason I can gather is that you need to flush data from
> > > lower levels of the cache below the point of unification.
> > > 
> > 
> > In deep sleep process, all caches will lost, so flush all caches to prevent
> > data loss.
> 
> You haven't answered my question.
> 

I want to flush L1 and L2 caches of Cortex-A7 in LS1021. However,
flush_cache_louis() only flushed L1 cache. Therefore, call
v7_flush_dcache_all() to flush L1 and L2 cache. 

> > > > +
> > > > +   /* disable cache, C bit in SCTLR */
> > > > +   mrc p15, 0, r0, c1, c0, 0
> > > > +   bic r0, r0, #(1 << 2)
> > > > +   mcr p15, 0, r0, c1, c0, 0
> > > > +   isb
> > > > +
> > > > +   /* disable coherency, SMP bit in ACTLR */
> > > > +   mrc p15, 0, r0, c1, c0, 1
> > > > +   bic r0, r0, #(1 << 6)
> > > > +   mcr p15, 0, r0, c1, c0, 1
> > > > +   isb
> > > > +   dsb
> > > > +
> > > > +   /* disable MMU, M bit in SCTLR */
> > > > +   mrc p15, 0, r0, c1, c0, 0
> > > > +   bic r0, r0, #1
> > > > +   mcr p15, 0, r0, c1, c0, 0
> > > > +   isb
> > > > +
> > > > +   /* jump to sram code using physical address */
> > > > +   bx  r13
> > > 
> > > This looks extremely fragile.  You are running in virtual space, and you
> > > turn the MMU off.  You are reliant on the MMU still being on for the
> > > following instructions to already be in the pipeline.  That's not a
> > > very good assumption to make (we've made it in the past and it breaks
> > > every so often when things change, eg when the code is no longer laid
> > > out how we expect.)
> > > 
> > > You need to disable the MMU safely, which means using the identity map
> > > page tables and executing code in the identity map region.
> > 
> > Yes, the code will switch off MMU, and switch to physical address space.
> > On LS1021, the DDR memory located at the physical address space started from
> > 0x8000, the kernel space also started at 0x8000 (CONFIG_PAGE_OFFSET 
> > = 0x8000).
> > So the virtual address of kernel code is equal to the physical address.
> 
> You can't rely on that.
> 
> Sorry, NAK.

I'll try to use a safer method to implement it.

Chenhui
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] arm: pm: add deep sleep support for LS1

2014-09-28 Thread Chenhui Zhao
On Fri, Sep 26, 2014 at 01:14:27PM +0100, Russell King - ARM Linux wrote:
> On Fri, Sep 26, 2014 at 07:25:03PM +0800, Chenhui Zhao wrote:
> > +static int ls1_start_deepsleep(unsigned long addr)
> > +{
> > +   ls1_do_deepsleep(addr);
> > +
> > +   return 0;
> > +}
> ...
> > +   cpu_suspend(SRAM_CODE_BASE_PHY, ls1_start_deepsleep);
> 
> What's the point of this function?  Why can't ls1_do_deepsleep() just
> return zero?

Just leave space for adding C code in the future.

> 
> > +/*
> > + * r0: the physical entry address of SRAM code
> > + *
> > + */
> > +ENTRY(ls1_do_deepsleep)
> > +   mov r13, r0
> > +
> > +   /* flush cache */
> > +   bl  v7_flush_dcache_all
> 
> Please explain the purpose of this call via a comment in the code.
> 
> The generic code will have saved the CPU state, and will have called
> flush_cache_louis() to flush the caches to the point of unification.
> 
> The only data which will have been loaded into the cache between that
> point is the stack for the return from __cpu_suspend_save, and
> speculative prefetches.
> 
> So, the only reason I can gather is that you need to flush data from
> lower levels of the cache below the point of unification.
> 

In deep sleep process, all caches will lost, so flush all caches to prevent
data loss.

> > +
> > +   /* disable cache, C bit in SCTLR */
> > +   mrc p15, 0, r0, c1, c0, 0
> > +   bic r0, r0, #(1 << 2)
> > +   mcr p15, 0, r0, c1, c0, 0
> > +   isb
> > +
> > +   /* disable coherency, SMP bit in ACTLR */
> > +   mrc p15, 0, r0, c1, c0, 1
> > +   bic r0, r0, #(1 << 6)
> > +   mcr p15, 0, r0, c1, c0, 1
> > +   isb
> > +   dsb
> > +
> > +   /* disable MMU, M bit in SCTLR */
> > +   mrc p15, 0, r0, c1, c0, 0
> > +   bic r0, r0, #1
> > +   mcr p15, 0, r0, c1, c0, 0
> > +   isb
> > +
> > +   /* jump to sram code using physical address */
> > +   bx  r13
> 
> This looks extremely fragile.  You are running in virtual space, and you
> turn the MMU off.  You are reliant on the MMU still being on for the
> following instructions to already be in the pipeline.  That's not a
> very good assumption to make (we've made it in the past and it breaks
> every so often when things change, eg when the code is no longer laid
> out how we expect.)
> 
> You need to disable the MMU safely, which means using the identity map
> page tables and executing code in the identity map region.

Yes, the code will switch off MMU, and switch to physical address space.
On LS1021, the DDR memory located at the physical address space started from
0x8000, the kernel space also started at 0x8000 (CONFIG_PAGE_OFFSET = 
0x8000).
So the virtual address of kernel code is equal to the physical address.

Chenhui
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] pm: add FSM configuration for deep sleep

2014-09-28 Thread Chenhui Zhao
On Fri, Sep 26, 2014 at 09:51:53PM +0100, Russell King - ARM Linux wrote:
> On Fri, Sep 26, 2014 at 01:02:01PM +0100, Russell King - ARM Linux wrote:
> > On Fri, Sep 26, 2014 at 07:25:02PM +0800, Chenhui Zhao wrote:
> > > +void fsm_write32(void __iomem *addr, u32 val)
> > > +{
> > > +#ifdef __arm__
> > > + iowrite32be(val, addr);
> > > +#endif
> > > +
> > > +#ifdef __powerpc__
> > > + out_be32(addr, val);
> > > +#endif
> > 
> > The idea of iowrite* is that it should be able to address MMIO or IO
> > memory irrespective of the platform.  Why is PowerPC not implementing
> > this accessor, or why can't it be used for PowerPC?
> > 
> > This should just use iowrite32be(), and if it doesn't work on PowerPC,
> > PowerPC needs to be fixed.
> 
> BenH tells me that this should be able to use iowrite32be() on PowerPC
> too without problems, there should be no need to use the older out_be32()
> accessors here.  Please can you look into using only iowrite32be() here?
> 
> Thanks.
> 

Thanks. I'll fix it.

Chenhui
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] pm: add FSM configuration for deep sleep

2014-09-26 Thread Chenhui Zhao
For some Freescale's SoCs which support deep sleep, such as T1040,
LS1021, software will start a Finite State Machine (FSM) to control
the hardware precedure to enter deep sleep and return from it.

This patch configures parameters of the FSM preparing for deep sleep.

Signed-off-by: Chenhui Zhao 
---
 drivers/platform/Kconfig |1 +
 drivers/platform/Makefile|1 +
 drivers/platform/fsl/Kconfig |   10 ++
 drivers/platform/fsl/Makefile|5 +
 drivers/platform/fsl/sleep_fsm.c |  281 ++
 drivers/platform/fsl/sleep_fsm.h |  100 ++
 6 files changed, 398 insertions(+), 0 deletions(-)
 create mode 100644 drivers/platform/fsl/Kconfig
 create mode 100644 drivers/platform/fsl/Makefile
 create mode 100644 drivers/platform/fsl/sleep_fsm.c
 create mode 100644 drivers/platform/fsl/sleep_fsm.h

diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 69616ae..54ada25 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -5,3 +5,4 @@ if GOLDFISH
 source "drivers/platform/goldfish/Kconfig"
 endif
 
+source "drivers/platform/fsl/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index 8a44a4c..d0cce95 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_X86)  += x86/
 obj-$(CONFIG_OLPC) += olpc/
 obj-$(CONFIG_GOLDFISH) += goldfish/
+obj-$(CONFIG_FSL_SOC)  += fsl/
diff --git a/drivers/platform/fsl/Kconfig b/drivers/platform/fsl/Kconfig
new file mode 100644
index 000..72ed053
--- /dev/null
+++ b/drivers/platform/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale Specific Power Management Drivers
+#
+
+config FSL_SLEEP_FSM
+   bool
+   help
+ This driver configures a hardware FSM (Finite State Machine) for deep 
sleep.
+ The FSM is used to finish clean-ups at the last stage of system 
entering deep
+ sleep, and also wakes up system when a wake up event happens.
diff --git a/drivers/platform/fsl/Makefile b/drivers/platform/fsl/Makefile
new file mode 100644
index 000..d99ca0e
--- /dev/null
+++ b/drivers/platform/fsl/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/fsl
+# Freescale Specific Power Management Drivers
+#
+obj-$(CONFIG_FSL_SLEEP_FSM)+= sleep_fsm.o
diff --git a/drivers/platform/fsl/sleep_fsm.c b/drivers/platform/fsl/sleep_fsm.c
new file mode 100644
index 000..d8478a1
--- /dev/null
+++ b/drivers/platform/fsl/sleep_fsm.c
@@ -0,0 +1,281 @@
+/*
+ * Freescale deep sleep FSM (finite-state machine) configuration
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#include "sleep_fsm.h"
+/*
+ * These values are from chip's reference manual. For example,
+ * the values for T1040 can be found in "8.4.3.8 Programming
+ * supporting deep sleep mode" of Chapter 8 "Run Control and
+ * Power Management (RCPM)".
+ * The default value can be applied to T104x, LS1021.
+ */
+struct fsm_reg_vals epu_default_val[] = {
+   /* EPGCR (Event Processor Global Control Register) */
+   {EPGCR, 0},
+   /* EPECR (Event Processor Event Control Registers) */
+   {EPECR0 + EPECR_STRIDE * 0, 0},
+   {EPECR0 + EPECR_STRIDE * 1, 0},
+   {EPECR0 + EPECR_STRIDE * 2, 0xF0004004},
+   {EPECR0 + EPECR_STRIDE * 3, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 4, 0x2084},
+   {EPECR0 + EPECR_STRIDE * 5, 0x0804},
+   {EPECR0 + EPECR_STRIDE * 6, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 7, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 8, 0x6084},
+   {EPECR0 + EPECR_STRIDE * 9, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 10, 0x4284},
+   {EPECR0 + EPECR_STRIDE * 11, 0x9084},
+   {EPECR0 + EPECR_STRIDE * 12, 0x8084},
+   {EPECR0 + EPECR_STRIDE * 13, 0x0884},
+   {EPECR0 + EPECR_STRIDE * 14, 0x0284},
+   /* This will be written just before entering deep sleep */
+   {EPECR0 + EPECR_STRIDE * 15, 0},
+   /*
+* EPEVTCR (Event Processor EVT Pin Control Registers)
+* SCU8 triger EVT2, and SCU11 triger EVT9
+*/
+   {EPEVTCR0 + EPEVTCR_STRIDE * 0, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 1, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 2, 0x8001},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 3, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 4, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 5, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 6, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 7, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 8, 0},
+   {EPEVTCR0 + EPEVTCR_STRIDE * 9, 0xB001},
+   /* EPCMPR (Event Processor Counte

[PATCH 3/3] arm: pm: add deep sleep support for LS1

2014-09-26 Thread Chenhui Zhao
LS1 supports deep sleep feature that can switch off most parts of
the SoC when it is in deep sleep state.

The DDR controller will also be powered off in deep sleep. Therefore,
copy the last stage code to enter deep sleep to SRAM and run it
with disabling MMU and caches.

Signed-off-by: Chenhui Zhao 
---
 arch/arm/mach-imx/Kconfig |1 +
 arch/arm/mach-imx/Makefile|1 +
 arch/arm/mach-imx/pm-ls1.c|  329 +
 arch/arm/mach-imx/sleep-ls1.S |  142 ++
 4 files changed, 473 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-imx/pm-ls1.c
 create mode 100644 arch/arm/mach-imx/sleep-ls1.S

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index b85534c..716bb1b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -866,6 +866,7 @@ config SOC_LS1021A
select HAVE_SMP
select ARCH_LAYERSCAPE
select ZONE_DMA if ARM_LPAE
+   select FSL_SLEEP_FSM if PM
 
help
  This enable support for Freescale Layerscape LS1021A  processor.
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 41b8044..9931528 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
 
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
+obj-$(CONFIG_SOC_LS1021A) += pm-ls1.o sleep-ls1.o
 endif
 
 # i.MX5 based machines
diff --git a/arch/arm/mach-imx/pm-ls1.c b/arch/arm/mach-imx/pm-ls1.c
new file mode 100644
index 000..621fdb4
--- /dev/null
+++ b/arch/arm/mach-imx/pm-ls1.c
@@ -0,0 +1,329 @@
+/*
+ * Support deep sleep feature for LS1
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define FSL_SLEEP  0x1
+#define FSL_DEEP_SLEEP 0x2
+
+#define DCSR_EPU_EPECR00x300
+#define DCSR_RCPM_CG1CR0   0x31c
+#define DCSR_RCPM_CSTTACR0 0xb00
+
+/* in SCFG registers except for SPARECR registers, reverse bits in each byte */
+#define CCSR_SCFG_DPSLPCR  0
+#define CCSR_SCFG_DPSLPCR_VAL  0x0080
+#define CCSR_SCFG_SPARECR2 0x504
+#define CCSR_SCFG_SPARECR3 0x508
+
+#define CCSR_DCFG_CRSTSR   0x400
+#define CCSR_DCFG_CRSTSR_VAL   0x0008
+
+#define CCSR_RCPM_POWMGTCSR0x130
+#define CCSR_RCPM_POWMGTCSR_LPM20_REQ  0x0010
+#define CCSR_RCPM_POWMGTCSR_LPM20_ST   0x0200
+#define CCSR_RCPM_POWMGTCSR_P_LPM20_ST 0x0100
+#define CCSR_RCPM_CLPCL10SETR  0x1c4
+#define CCSR_RCPM_CLPCL10SETR_C0   0x1
+
+#define QIXIS_CTL_SYS  0x5
+#define QIXIS_CTL_SYS_EVTSW_MASK   0x0c
+#define QIXIS_CTL_SYS_EVTSW_IRQ0x04
+
+#define QIXIS_PWR_CTL2 0x21
+#define QIXIS_PWR_CTL2_PCTL0x2
+
+#define OCRAM_BASE 0x1000
+#define OCRAM_SIZE 0x1 /* 64K */
+/* use the last page of SRAM */
+#define SRAM_CODE_BASE_PHY (OCRAM_BASE + OCRAM_SIZE - PAGE_SIZE)
+
+struct ls1_pm_baseaddr {
+   void __iomem *epu;
+   void __iomem *dcsr_rcpm1;
+   void __iomem *dcsr_rcpm2;
+   void __iomem *rcpm;
+   void __iomem *scfg;
+   void __iomem *dcfg;
+   void __iomem *fpga;
+   void __iomem *sram;
+};
+
+/* 128 bytes buffer for restoring data broke by DDR training initialization */
+#define DDR_BUF_SIZE   128
+static u8 ddr_buff[DDR_BUF_SIZE] __aligned(64);
+static struct ls1_pm_baseaddr ls1_pm_base;
+/* supported sleep modes by the present platform */
+static unsigned int sleep_modes;
+
+extern void ls1_do_deepsleep(unsigned long addr);
+extern void ls1_start_fsm(void);
+extern void ls1_deepsleep_resume(void);
+extern void ls1021a_set_secondary_entry(void);
+extern int ls1_sram_code_size;
+extern void fsl_epu_setup_default(void __iomem *epu_base);
+
+static void ls1_pm_iomap(void)
+{
+   struct device_node *np;
+   void *base;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcsr-epu");
+   base = of_iomap(np, 0);
+   BUG_ON(!base);
+   ls1_pm_base.epu = base;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcsr-rcpm");
+   base = of_iomap(np, 0);
+   BUG_ON(!base);
+   ls1_pm_base.dcsr_rcpm1 = base;
+   base = of_iomap(np, 1);
+   BUG_ON(!base);
+   ls1_pm_base.dcsr_rcpm2 = base;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-scfg");
+   base = of_iomap(np, 0);
+   BUG_ON(!base);
+   ls1_pm_base.scfg = base;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg");
+   base

[PATCH 0/3] arm: ls1: add deep sleep support

2014-09-26 Thread Chenhui Zhao
These patches are for supporting deep sleep on LS1.
They are based on the platform patches for LS1.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] arm: ls1: add CPU hotplug platform support

2014-09-26 Thread Chenhui Zhao
From: Zhang Zhuoyu 

This implements CPU hotplug for ls1. When cpu is down, it will be put
in WFI state. When cpu is up, it will be waked by a IPI interrupt and
reinitialized.

Signed-off-by: Zhang Zhuoyu 
Signed-off-by: Chenhui Zhao 
---
 arch/arm/mach-imx/common.h  |4 ++
 arch/arm/mach-imx/hotplug.c |   90 +++
 arch/arm/mach-imx/platsmp.c |   22 --
 arch/arm/mach-imx/src.c |   21 ++
 4 files changed, 132 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 203ee73..2ca32fe 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -115,6 +115,7 @@ void tzic_handle_irq(struct pt_regs *);
 extern void imx_enable_cpu(int cpu, bool enable);
 extern void imx_set_cpu_jump(int cpu, void *jump_addr);
 extern u32 imx_get_cpu_arg(int cpu);
+extern u32 ls1_get_cpu_arg(int cpu);
 extern void imx_set_cpu_arg(int cpu, u32 arg);
 extern void v7_cpu_resume(void);
 #ifdef CONFIG_SMP
@@ -145,6 +146,9 @@ extern void imx6q_set_chicken_bit(void);
 extern void imx_cpu_die(unsigned int cpu);
 extern int imx_cpu_kill(unsigned int cpu);
 
+extern void ls1021a_cpu_die(unsigned int cpu);
+extern int ls1021a_cpu_kill(unsigned int cpu);
+
 #ifdef CONFIG_PM
 extern void imx6q_pm_init(void);
 extern void imx5_pm_init(void);
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
index 3daf1ed..646034f 100644
--- a/arch/arm/mach-imx/hotplug.c
+++ b/arch/arm/mach-imx/hotplug.c
@@ -14,6 +14,9 @@
 #include 
 #include 
 #include 
+#include
+#include
+#include
 
 #include "common.h"
 
@@ -38,6 +41,22 @@ static inline void cpu_enter_lowpower(void)
  : "cc");
 }
 
+static inline void cpu_leave_lowpower(void)
+{
+   unsigned int v;
+
+   asm volatile(
+   "   mrc p15, 0, %0, c1, c0, 0\n"
+   "   orr %0, %0, %1\n"
+   "   mcr p15, 0, %0, c1, c0, 0\n"
+   "   mrc p15, 0, %0, c1, c0, 1\n"
+   "   orr %0, %0, %2\n"
+   "   mcr p15, 0, %0, c1, c0, 1\n"
+   : "=&r" (v)
+   : "Ir" (CR_C), "Ir" (0x40)
+   : "cc");
+}
+
 /*
  * platform-specific code to shutdown a CPU
  *
@@ -66,3 +85,74 @@ int imx_cpu_kill(unsigned int cpu)
imx_set_cpu_arg(cpu, 0);
return 1;
 }
+
+static inline void ls1_do_lowpower(unsigned int cpu, int *spurious)
+{
+   /*
+* there is no power-control hardware on this platform, so all
+* we can do is put the core into WFI; this is safe as the calling
+* code will have already disabled interrupts
+*/
+   for (;;) {
+   wfi();
+
+   if (pen_release == cpu_logical_map(cpu)) {
+   /*OK, proper wakeup, we're done*/
+   break;
+   }
+
+   /*
+* Getting here, means that we have come out of WFI without
+* having been woken up - this shouldn't happen
+*
+* Just note it happening - when we're woken, we can report
+* its occurrence.
+*/
+   (*spurious)++;
+   }
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __ref ls1021a_cpu_die(unsigned int cpu)
+{
+   int spurious = 0;
+
+   v7_exit_coherency_flush(louis);
+
+   /*we're ready for shutdown now, so do it*/
+   ls1_do_lowpower(cpu, &spurious);
+
+   /*
+* bring this CPU back into the world of cache
+* coherency, and then restore interrupts
+*/
+   cpu_leave_lowpower();
+
+   if (spurious)
+   pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+
+   /*
+* Do not return to the idle loop - jump back to the secondary
+* cpu initialisation.  There's some initialisation which needs
+* to be repeated to undo the effects of taking the CPU offline.
+*/
+   __asm__("movsp, %0\n"
+   "   mov fp, #0\n"
+   "   b   ls1021a_secondary_startup"
+   :
+   : "r" (task_stack_page(current) + THREAD_SIZE - 8));
+}
+
+int ls1021a_cpu_kill(unsigned int cpu)
+{
+   unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
+   while (ls1_get_cpu_arg(cpu))
+   if (time_after(jiffies, timeout))
+   return 0;
+   return 1;
+}
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index 5225b69..d262b32 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -29,6 +29,7 @@
 
 u32 g_diag_reg;
 static void __iomem *scu_base;
+void __iomem *dcfg_base;
 
 static struct map_desc scu_io_desc __initdata = {
/* .virtual and .pfn are run-ti

Re: [PATCH 9/9] powerpc/pm: support deep sleep feature on T1040

2014-03-18 Thread Chenhui Zhao
On Tue, Mar 18, 2014 at 05:42:09PM -0500, Scott Wood wrote:
> On Mon, 2014-03-17 at 19:19 +0800, Chenhui Zhao wrote:
> > On Fri, Mar 14, 2014 at 06:18:27PM -0500, Scott Wood wrote:
> > > On Wed, 2014-03-12 at 18:40 +0800, Chenhui Zhao wrote:
> > > > On Tue, Mar 11, 2014 at 08:10:24PM -0500, Scott Wood wrote:
> > > > > On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > > > > > From: Zhao Chenhui 
> > > > > > 
> > > > > > T1040 supports deep sleep feature, which can switch off most parts 
> > > > > > of
> > > > > > the SoC when it is in deep sleep mode. This way, it becomes more
> > > > > > energy-efficient.
> > > > > > 
> > > > > > The DDR controller will also be powered off in deep sleep. 
> > > > > > Therefore,
> > > > > > the last stage (the latter part of fsl_dp_enter_low) will run 
> > > > > > without DDR
> > > > > > access. This piece of code and related TLBs will be prefetched.
> > > > > > 
> > > > > > Due to the different initialization code between 32-bit and 64-bit, 
> > > > > > they
> > > > > > have seperate resume entry and precedure.
> > > > > > 
> > > > > > The feature supports 32-bit and 64-bit kernel mode.
> > > > > > 
> > > > > > Signed-off-by: Zhao Chenhui 
> > > > > > ---
> > > > > >  arch/powerpc/include/asm/booke_save_regs.h |3 +
> > > > > >  arch/powerpc/kernel/cpu_setup_fsl_booke.S  |   17 ++
> > > > > >  arch/powerpc/kernel/head_fsl_booke.S   |   30 +++
> > > > > >  arch/powerpc/platforms/85xx/Makefile   |2 +-
> > > > > >  arch/powerpc/platforms/85xx/deepsleep.c|  201 
> > > > > > +++
> > > > > >  arch/powerpc/platforms/85xx/qoriq_pm.c |   38 
> > > > > >  arch/powerpc/platforms/85xx/sleep.S|  295 
> > > > > > 
> > > > > >  arch/powerpc/sysdev/fsl_soc.h  |7 +
> > > > > >  8 files changed, 592 insertions(+), 1 deletions(-)
> > > > > >  create mode 100644 arch/powerpc/platforms/85xx/deepsleep.c
> > > > > >  create mode 100644 arch/powerpc/platforms/85xx/sleep.S
> > > > > > 
> > > > > > diff --git a/arch/powerpc/include/asm/booke_save_regs.h 
> > > > > > b/arch/powerpc/include/asm/booke_save_regs.h
> > > > > > index 87c357a..37c1f6c 100644
> > > > > > --- a/arch/powerpc/include/asm/booke_save_regs.h
> > > > > > +++ b/arch/powerpc/include/asm/booke_save_regs.h
> > > > > > @@ -88,6 +88,9 @@
> > > > > >  #define HIBERNATION_FLAG   1
> > > > > >  #define DEEPSLEEP_FLAG 2
> > > > > >  
> > > > > > +#define CPLD_FLAG  1
> > > > > > +#define FPGA_FLAG  2
> > > > > 
> > > > > What is this?
> > > > 
> > > > We have two kind of boards, QDS and RDB.
> > > > They have different register map. Use the flag to indicate the current 
> > > > board is using which kind
> > > > of register map.
> > > 
> > > CPLD versus FPGA is not a meaningful difference.  We don't care what
> > > technology is used to implement programmable logic -- we care what
> > > programming interface is exposed.  Customers will have their own boards
> > > that will likely not imitate either of these programming interfaces, but
> > > what they do have will still probably be implemented in a CPLD or FPGA.
> > > Likewise, Freescale may have future reference boards whose CPLD/FPGA is
> > > not compatible.
> > 
> > Will use a better name.
> > 
> > > 
> > > So use better naming, and structure the code so it's easy to plug in
> > > implementations for new or custom boards.
> > >  
> > > > > > diff --git a/arch/powerpc/kernel/head_fsl_booke.S 
> > > > > > b/arch/powerpc/kernel/head_fsl_booke.S
> > > > > > index 20204fe..3285752 100644
> > > > > > --- a/arch/powerpc/kernel/head_fsl_booke.S
> > > > > > +++ b/arch/powerpc/kernel/head_fsl_booke.S
> > > > > > @@ -162,6 +162,19 @@ _ENTRY(__early_start)
> > > > > >  #include "

Re: [PATCH 7/9] fsl: add EPU FSM configuration for deep sleep

2014-03-18 Thread Chenhui Zhao
On Tue, Mar 18, 2014 at 06:21:22PM -0500, Scott Wood wrote:
> On Mon, 2014-03-17 at 18:27 +0800, Chenhui Zhao wrote:
> > On Fri, Mar 14, 2014 at 05:51:09PM -0500, Scott Wood wrote:
> > > On Wed, 2014-03-12 at 16:34 +0800, Chenhui Zhao wrote:
> > > > On Tue, Mar 11, 2014 at 07:08:43PM -0500, Scott Wood wrote:
> > > > > On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > > > > > +   /* Configure the EPU Counters */
> > > > > > +   epu_write(EPCCR15, 0x9284);
> > > > > > +   epu_write(EPCCR14, 0x9284);
> > > > > > +   epu_write(EPCCR12, 0x9284);
> > > > > > +   epu_write(EPCCR11, 0x9284);
> > > > > > +   epu_write(EPCCR10, 0x9284);
> > > > > > +   epu_write(EPCCR9, 0x9284);
> > > > > > +   epu_write(EPCCR8, 0x9284);
> > > > > > +   epu_write(EPCCR5, 0x9284);
> > > > > > +   epu_write(EPCCR4, 0x9284);
> > > > > > +   epu_write(EPCCR2, 0x9284);
> > > > > > +
> > > > > > +   /* Configure the SCUs Inputs */
> > > > > > +   epu_write(EPSMCR15, 0x7600);
> > > > > > +   epu_write(EPSMCR14, 0x0031);
> > > > > > +   epu_write(EPSMCR13, 0x3100);
> > > > > > +   epu_write(EPSMCR12, 0x7F00);
> > > > > > +   epu_write(EPSMCR11, 0x3174);
> > > > > > +   epu_write(EPSMCR10, 0x6530);
> > > > > > +   epu_write(EPSMCR9, 0x3000);
> > > > > > +   epu_write(EPSMCR8, 0x6430);
> > > > > > +   epu_write(EPSMCR7, 0x3000);
> > > > > > +   epu_write(EPSMCR6, 0x7C00);
> > > > > > +   epu_write(EPSMCR5, 0x2E00);
> > > > > > +   epu_write(EPSMCR4, 0x002F);
> > > > > > +   epu_write(EPSMCR3, 0x2F00);
> > > > > > +   epu_write(EPSMCR2, 0x6C70);
> > > > > 
> > > > > Where do these magic numbers come from?  Which chips are they valid 
> > > > > for?
> > > > 
> > > > They are for T1040. Can be found in the RCPM chapter of T1040RM.
> > > 
> > > Then put in a comment to that effect, including what part of the RCPM
> > > chapter.
> > > 
> > > How do you plan to handle the addition of another SoC with different
> > > values?
> > > 
> > > -Scott
> > 
> > Had thought that using an array to put these values (pairs of offset and 
> > value)
> > and passing the array to the function.
> 
> Arrays are better than a long sequence of function calls in any case.
> 
> > However, luckily T104x and LS1 have same values for these registers
> > according to the current Reference Manuals.
> 
> If it's likely that the values will remain the same on all chips for the
> near future, then a fancy mechanism to select the array to use can wait
> -- but you should still use an array, and have a comment acknowledging
> the possibility of needing to accommodate different values in the
> future.
> 
> -Scott

OK. Will use an array to pass the values.

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 9/9] powerpc/pm: support deep sleep feature on T1040

2014-03-17 Thread Chenhui Zhao
On Fri, Mar 14, 2014 at 06:18:27PM -0500, Scott Wood wrote:
> On Wed, 2014-03-12 at 18:40 +0800, Chenhui Zhao wrote:
> > On Tue, Mar 11, 2014 at 08:10:24PM -0500, Scott Wood wrote:
> > > On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > > > From: Zhao Chenhui 
> > > > 
> > > > T1040 supports deep sleep feature, which can switch off most parts of
> > > > the SoC when it is in deep sleep mode. This way, it becomes more
> > > > energy-efficient.
> > > > 
> > > > The DDR controller will also be powered off in deep sleep. Therefore,
> > > > the last stage (the latter part of fsl_dp_enter_low) will run without 
> > > > DDR
> > > > access. This piece of code and related TLBs will be prefetched.
> > > > 
> > > > Due to the different initialization code between 32-bit and 64-bit, they
> > > > have seperate resume entry and precedure.
> > > > 
> > > > The feature supports 32-bit and 64-bit kernel mode.
> > > > 
> > > > Signed-off-by: Zhao Chenhui 
> > > > ---
> > > >  arch/powerpc/include/asm/booke_save_regs.h |3 +
> > > >  arch/powerpc/kernel/cpu_setup_fsl_booke.S  |   17 ++
> > > >  arch/powerpc/kernel/head_fsl_booke.S   |   30 +++
> > > >  arch/powerpc/platforms/85xx/Makefile   |2 +-
> > > >  arch/powerpc/platforms/85xx/deepsleep.c|  201 +++
> > > >  arch/powerpc/platforms/85xx/qoriq_pm.c |   38 
> > > >  arch/powerpc/platforms/85xx/sleep.S|  295 
> > > > 
> > > >  arch/powerpc/sysdev/fsl_soc.h  |7 +
> > > >  8 files changed, 592 insertions(+), 1 deletions(-)
> > > >  create mode 100644 arch/powerpc/platforms/85xx/deepsleep.c
> > > >  create mode 100644 arch/powerpc/platforms/85xx/sleep.S
> > > > 
> > > > diff --git a/arch/powerpc/include/asm/booke_save_regs.h 
> > > > b/arch/powerpc/include/asm/booke_save_regs.h
> > > > index 87c357a..37c1f6c 100644
> > > > --- a/arch/powerpc/include/asm/booke_save_regs.h
> > > > +++ b/arch/powerpc/include/asm/booke_save_regs.h
> > > > @@ -88,6 +88,9 @@
> > > >  #define HIBERNATION_FLAG   1
> > > >  #define DEEPSLEEP_FLAG 2
> > > >  
> > > > +#define CPLD_FLAG  1
> > > > +#define FPGA_FLAG  2
> > > 
> > > What is this?
> > 
> > We have two kind of boards, QDS and RDB.
> > They have different register map. Use the flag to indicate the current 
> > board is using which kind
> > of register map.
> 
> CPLD versus FPGA is not a meaningful difference.  We don't care what
> technology is used to implement programmable logic -- we care what
> programming interface is exposed.  Customers will have their own boards
> that will likely not imitate either of these programming interfaces, but
> what they do have will still probably be implemented in a CPLD or FPGA.
> Likewise, Freescale may have future reference boards whose CPLD/FPGA is
> not compatible.

Will use a better name.

> 
> So use better naming, and structure the code so it's easy to plug in
> implementations for new or custom boards.
>  
> > > > diff --git a/arch/powerpc/kernel/head_fsl_booke.S 
> > > > b/arch/powerpc/kernel/head_fsl_booke.S
> > > > index 20204fe..3285752 100644
> > > > --- a/arch/powerpc/kernel/head_fsl_booke.S
> > > > +++ b/arch/powerpc/kernel/head_fsl_booke.S
> > > > @@ -162,6 +162,19 @@ _ENTRY(__early_start)
> > > >  #include "fsl_booke_entry_mapping.S"
> > > >  #undef ENTRY_MAPPING_BOOT_SETUP
> > > >  
> > > > +#if defined(CONFIG_SUSPEND) && defined(CONFIG_FSL_CORENET_RCPM)
> > > > +   /* if deep_sleep_flag != 0, jump to the deep sleep resume entry 
> > > > */
> > > > +   LOAD_REG_ADDR(r4, deep_sleep_flag)
> > > > +   lwz r3, 0(r4)
> > > > +   cmpwi   r3, 0
> > > > +   beq 11f
> > > > +   /* clear deep_sleep_flag */
> > > > +   li  r3, 0
> > > > +   stw r3, 0(r4)
> > > > +   b   fsl_deepsleep_resume
> > > > +11:
> > > > +#endif
> > > 
> > > Why do you come in via the normal kernel entry, versus specifying a
> > > direct entry point for deep sleep resume?  How does U-Boot even know
> > > what the normal entry is w

Re: [PATCH 8/9] powerpc/85xx: add save/restore functions for core registers

2014-03-17 Thread Chenhui Zhao
On Fri, Mar 14, 2014 at 06:01:45PM -0500, Scott Wood wrote:
> On Wed, 2014-03-12 at 17:42 +0800, Chenhui Zhao wrote:
> > On Tue, Mar 11, 2014 at 07:45:14PM -0500, Scott Wood wrote:
> > > On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > > > From: Wang Dongsheng 
> > > > 
> > > > Add booke_cpu_state_save() and booke_cpu_state_restore() functions 
> > > > which can be
> > > > used to save/restore CPU's registers in the case of deep sleep and 
> > > > hibernation.
> > > > 
> > > > Supported processors: E6500, E5500, E500MC, E500v2 and E500v1.
> > > > 
> > > > Signed-off-by: Wang Dongsheng 
> > > > Signed-off-by: Chenhui Zhao 
> > > > ---
> > > >  arch/powerpc/include/asm/booke_save_regs.h |   96 
> > > >  arch/powerpc/kernel/Makefile   |1 +
> > > >  arch/powerpc/kernel/booke_save_regs.S  |  361 
> > > > 
> > > >  3 files changed, 458 insertions(+), 0 deletions(-)
> > > >  create mode 100644 arch/powerpc/include/asm/booke_save_regs.h
> > > >  create mode 100644 arch/powerpc/kernel/booke_save_regs.S
> > > > 
> > > > diff --git a/arch/powerpc/include/asm/booke_save_regs.h 
> > > > b/arch/powerpc/include/asm/booke_save_regs.h
> > > > new file mode 100644
> > > > index 000..87c357a
> > > > --- /dev/null
> > > > +++ b/arch/powerpc/include/asm/booke_save_regs.h
> > > > @@ -0,0 +1,96 @@
> > > > +/*
> > > > + *  Save/restore e500 series core registers
> > > 
> > > Filename says booke, comment says e500.
> > > 
> > > Filename and comment also fail to point out that this is specifically
> > > for standby/suspend, not for hibernate which is implemented in
> > > swsusp_booke.S/swsusp_asm64.S.
> > 
> > Sorry for inconsistency. Will changes e500 to booke.
> > Hibernation and suspend can share the code.
> 
> Maybe they could, but AFAICT this patchset doesn't make that happen --
> and I'm not convinced that the churn would be worthwhile.  Note that
> swsusp_asm64.S is not just for booke, so most of that file would not be
> going away if you did make such a change.

OK. Let's put Hibernation aside, and change the code just for suspend.

> 
> I also don't like the way it looks like booke_save_regs.S is a booke
> version of ppc_save_regs.S, even though they serve different purposes
> and ppc_save_regs.S is still relevant to booke.
> 
> > > > + * Software-Use Registers
> > > > + * SPRG1   0x260   (dw * 76), 64-bit need 
> > > > to save.
> > > > + * SPRG3   0x268   (dw * 77), 32-bit need 
> > > > to save.
> > > 
> > > What about "CPU and NUMA node for VDSO getcpu" on 64-bit?  Currently
> > > SPRG3, but it will need to change for critical interrupt support.
> > > 
> > > > + * MMU Registers
> > > > + * PID0 - PID2 0x270 ~ 0x280   (dw * 78 ~ dw * 80)
> > > 
> > > PID1/PID2 are e500v1/v2 only -- and Linux doesn't use them outside of
> > > KVM (and you're not in KVM when you're running this code).
> > > 
> > > Are we ever going to have a non-zero PID at this point?
> > 
> > I incline to the view that saving all registers regardless of used or
> > unused. The good point is that it can be compliant to the future
> > changes of the usage of registers.
> > 
> > What do you think?
> 
> I agree to a certain extent, but balance it with the complexity of
> dealing with registers that don't exist on all booke chips.  If they
> don't really need to be saved, why go through the hassle of conditional
> code?

I agree. For these registers, I'll check if they are really needed.

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 7/9] fsl: add EPU FSM configuration for deep sleep

2014-03-17 Thread Chenhui Zhao
On Fri, Mar 14, 2014 at 05:51:09PM -0500, Scott Wood wrote:
> On Wed, 2014-03-12 at 16:34 +0800, Chenhui Zhao wrote:
> > On Tue, Mar 11, 2014 at 07:08:43PM -0500, Scott Wood wrote:
> > > On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > > > From: Hongbo Zhang 
> > > > 
> > > > In the last stage of deep sleep, software will trigger a Finite
> > > > State Machine (FSM) to control the hardware precedure, such as
> > > > board isolation, killing PLLs, removing power, and so on.
> > > > 
> > > > When the system is waked up by an interrupt, the FSM controls the
> > > > hardware to complete the early resume precedure.
> > > > 
> > > > This patch configure the EPU FSM preparing for deep sleep.
> > > > 
> > > > Signed-off-by: Hongbo Zhang 
> > > > Signed-off-by: Chenhui Zhao 
> > > 
> > > Couldn't this be part of qoriq_pm.c?
> > 
> > Put the code in drivers/platform/fsl/ so that LS1 can share these code.
> 
> How can LS1 share it if it's got hardcoded T1040 values?
> 
> > > > diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
> > > > index 09fde58..6539e6d 100644
> > > > --- a/drivers/platform/Kconfig
> > > > +++ b/drivers/platform/Kconfig
> > > > @@ -6,3 +6,7 @@ source "drivers/platform/goldfish/Kconfig"
> > > >  endif
> > > >  
> > > >  source "drivers/platform/chrome/Kconfig"
> > > > +
> > > > +if FSL_SOC
> > > > +source "drivers/platform/fsl/Kconfig"
> > > > +endif
> > > 
> > > Chrome doesn't need an ifdef -- why does this?
> > 
> > Don't wish other platform see these options, and the X86 and GOLDFISH have
> > ifdefs.
> 
> The point is you can implement the dependency inside
> drivers/platform/fsl/Kconfig.

OK.

> 
> > > > diff --git a/drivers/platform/fsl/Makefile 
> > > > b/drivers/platform/fsl/Makefile
> > > > new file mode 100644
> > > > index 000..d99ca0e
> > > > --- /dev/null
> > > > +++ b/drivers/platform/fsl/Makefile
> > > > @@ -0,0 +1,5 @@
> > > > +#
> > > > +# Makefile for linux/drivers/platform/fsl
> > > > +# Freescale Specific Power Management Drivers
> > > > +#
> > > > +obj-$(CONFIG_FSL_SLEEP_FSM)+= sleep_fsm.o
> > > 
> > > Why is this here while the other stuff is in arch/powerpc/sysdev?
> > > 
> > > > +/* Block offsets */
> > > > +#defineRCPM_BLOCK_OFFSET   0x00022000
> > > > +#defineEPU_BLOCK_OFFSET0x
> > > > +#defineNPC_BLOCK_OFFSET0x1000
> > > 
> > > Why don't these block offsets come from the device tree?
> > 
> > Have maped DCSR registers. Don't wish to remap them.
> 
> We don't wish to have hardcoded CCSR/DCSR offsets in the kernel source.
> Sorry.

OK.

>  
> > > > +   /* Configure the EPU Counters */
> > > > +   epu_write(EPCCR15, 0x9284);
> > > > +   epu_write(EPCCR14, 0x9284);
> > > > +   epu_write(EPCCR12, 0x9284);
> > > > +   epu_write(EPCCR11, 0x9284);
> > > > +   epu_write(EPCCR10, 0x9284);
> > > > +   epu_write(EPCCR9, 0x9284);
> > > > +   epu_write(EPCCR8, 0x9284);
> > > > +   epu_write(EPCCR5, 0x9284);
> > > > +   epu_write(EPCCR4, 0x9284);
> > > > +   epu_write(EPCCR2, 0x9284);
> > > > +
> > > > +   /* Configure the SCUs Inputs */
> > > > +   epu_write(EPSMCR15, 0x7600);
> > > > +   epu_write(EPSMCR14, 0x0031);
> > > > +   epu_write(EPSMCR13, 0x3100);
> > > > +   epu_write(EPSMCR12, 0x7F00);
> > > > +   epu_write(EPSMCR11, 0x3174);
> > > > +   epu_write(EPSMCR10, 0x6530);
> > > > +   epu_write(EPSMCR9, 0x3000);
> > > > +   epu_write(EPSMCR8, 0x6430);
> > > > +   epu_write(EPSMCR7, 0x3000);
> > > > +   epu_write(EPSMCR6, 0x7C00);
> > > > +   epu_write(EPSMCR5, 0x2E00);
> > > > +   epu_write(EPSMCR4, 0x002F);
> > > > +   epu_write(EPSMCR3, 0x2F00);
> > > > +   epu_write(EPSMCR2, 0x6C70);
> > > 
> > > Where do these magic numbers come from?  Which chips are they valid for?
> > 
> > They are for T1040. Can be found in the RCPM chapter of T1040RM.
> 
> Then put in a comment to that effect, including what part of the RCPM
> chapter.
> 
> How do you plan to handle the addition of another SoC with different
> values?
> 
> -Scott

Had thought that using an array to put these values (pairs of offset and value)
and passing the array to the function.

However, luckily T104x and LS1 have same values for these registers
according to the current Reference Manuals.

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 5/9] powerpc/85xx: disable irq by hardware when suspend for 64-bit

2014-03-17 Thread Chenhui Zhao
On Fri, Mar 14, 2014 at 05:41:41PM -0500, Scott Wood wrote:
> On Wed, 2014-03-12 at 15:46 +0800, Chenhui Zhao wrote:
> > On Tue, Mar 11, 2014 at 06:51:20PM -0500, Scott Wood wrote:
> > > On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > > > In 64-bit mode, kernel just clears the irq soft-enable flag
> > > > in struct paca_struct to disable external irqs. But, in
> > > > the case of suspend, irqs should be disabled by hardware.
> > > > Therefore, hook a function to ppc_md.suspend_disable_irqs
> > > > to really disable irqs.
> > > > 
> > > > Signed-off-by: Chenhui Zhao 
> > > > ---
> > > >  arch/powerpc/platforms/85xx/corenet_generic.c |   12 
> > > >  1 files changed, 12 insertions(+), 0 deletions(-)
> > > > 
> > > > diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c 
> > > > b/arch/powerpc/platforms/85xx/corenet_generic.c
> > > > index 3fdf9f3..983d81f 100644
> > > > --- a/arch/powerpc/platforms/85xx/corenet_generic.c
> > > > +++ b/arch/powerpc/platforms/85xx/corenet_generic.c
> > > > @@ -32,6 +32,13 @@
> > > >  #include 
> > > >  #include "smp.h"
> > > >  
> > > > +#if defined(CONFIG_PPC64) && defined(CONFIG_SUSPEND)
> > > > +static void fsl_suspend_disable_irqs(void)
> > > > +{
> > > > +   __hard_irq_disable();
> > > > +}
> > > > +#endif
> > > 
> > > Why the underscore version?  Don't you want PACA_IRQ_HARD_DIS to be set?
> > > 
> > > If hard disabling is appropriate here, shouldn't we do it in
> > > generic_suspend_disable_irqs()?
> > > 
> > > Are there any existing platforms that supply a
> > > ppc_md.suspend_disable_irqs()?  I don't see any when grepping.
> > > 
> > > -Scott
> > 
> > Will use hard_irq_disable().
> > 
> > I think this is a general problem for powerpc.
> > Should clear MSR_EE before suspend. I agree to put it
> > in generic_suspend_disable_irqs().
> 
> BTW, make sure you test this patchset with CONFIG_DEBUG_PREEMPT and
> similar debugging options to help ensure that the soft IRQ state is
> being tracked properly.
> 
> -Scott

OK. I'll keep that in mind.

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 9/9] powerpc/pm: support deep sleep feature on T1040

2014-03-12 Thread Chenhui Zhao
On Tue, Mar 11, 2014 at 08:10:24PM -0500, Scott Wood wrote:
> On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > From: Zhao Chenhui 
> > 
> > T1040 supports deep sleep feature, which can switch off most parts of
> > the SoC when it is in deep sleep mode. This way, it becomes more
> > energy-efficient.
> > 
> > The DDR controller will also be powered off in deep sleep. Therefore,
> > the last stage (the latter part of fsl_dp_enter_low) will run without DDR
> > access. This piece of code and related TLBs will be prefetched.
> > 
> > Due to the different initialization code between 32-bit and 64-bit, they
> > have seperate resume entry and precedure.
> > 
> > The feature supports 32-bit and 64-bit kernel mode.
> > 
> > Signed-off-by: Zhao Chenhui 
> > ---
> >  arch/powerpc/include/asm/booke_save_regs.h |3 +
> >  arch/powerpc/kernel/cpu_setup_fsl_booke.S  |   17 ++
> >  arch/powerpc/kernel/head_fsl_booke.S   |   30 +++
> >  arch/powerpc/platforms/85xx/Makefile   |2 +-
> >  arch/powerpc/platforms/85xx/deepsleep.c|  201 +++
> >  arch/powerpc/platforms/85xx/qoriq_pm.c |   38 
> >  arch/powerpc/platforms/85xx/sleep.S|  295 
> > 
> >  arch/powerpc/sysdev/fsl_soc.h  |7 +
> >  8 files changed, 592 insertions(+), 1 deletions(-)
> >  create mode 100644 arch/powerpc/platforms/85xx/deepsleep.c
> >  create mode 100644 arch/powerpc/platforms/85xx/sleep.S
> > 
> > diff --git a/arch/powerpc/include/asm/booke_save_regs.h 
> > b/arch/powerpc/include/asm/booke_save_regs.h
> > index 87c357a..37c1f6c 100644
> > --- a/arch/powerpc/include/asm/booke_save_regs.h
> > +++ b/arch/powerpc/include/asm/booke_save_regs.h
> > @@ -88,6 +88,9 @@
> >  #define HIBERNATION_FLAG   1
> >  #define DEEPSLEEP_FLAG 2
> >  
> > +#define CPLD_FLAG  1
> > +#define FPGA_FLAG  2
> 
> What is this?

We have two kind of boards, QDS and RDB. They have different register
map. Use the flag to indicate the current board is using which kind
of register map.

> 
> >  #ifndef __ASSEMBLY__
> >  extern void booke_cpu_state_save(void *buf, int type);
> >  extern void *booke_cpu_state_restore(void *buf, int type);
> > diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S 
> > b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
> > index e59d6de..ea9bc28 100644
> > --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
> > +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
> > @@ -318,6 +318,23 @@ flush_backside_L2_cache:
> >  2:
> > blr
> >  
> > +#define CPC_CPCCSR00x0
> > +#define CPC_CPCCSR0_CPCFL  0x800
> 
> This is supposed to be CPU setup, not platform setup.
> 
> > +/* r3 : the base address of CPC  */
> > +_GLOBAL(fsl_flush_cpc_cache)
> > +   lwz r6, CPC_CPCCSR0(r3)
> > +   ori r6, r6, CPC_CPCCSR0_CPCFL
> > +   stw r6, CPC_CPCCSR0(r3)
> > +   sync
> > +
> > +   /* Wait until completing the flush */
> > +1: lwz r6, CPC_CPCCSR0(r3)
> > +   andi.   r6, r6, CPC_CPCCSR0_CPCFL
> > +   bne 1b
> > +
> > +   blr
> > +
> >  _GLOBAL(__flush_caches_e500v2)
> 
> I'm not sure that this belongs here either.

Will find a better place.

> 
> > mflr r0
> > bl  flush_dcache_L1
> > diff --git a/arch/powerpc/kernel/head_fsl_booke.S 
> > b/arch/powerpc/kernel/head_fsl_booke.S
> > index 20204fe..3285752 100644
> > --- a/arch/powerpc/kernel/head_fsl_booke.S
> > +++ b/arch/powerpc/kernel/head_fsl_booke.S
> > @@ -162,6 +162,19 @@ _ENTRY(__early_start)
> >  #include "fsl_booke_entry_mapping.S"
> >  #undef ENTRY_MAPPING_BOOT_SETUP
> >  
> > +#if defined(CONFIG_SUSPEND) && defined(CONFIG_FSL_CORENET_RCPM)
> > +   /* if deep_sleep_flag != 0, jump to the deep sleep resume entry */
> > +   LOAD_REG_ADDR(r4, deep_sleep_flag)
> > +   lwz r3, 0(r4)
> > +   cmpwi   r3, 0
> > +   beq 11f
> > +   /* clear deep_sleep_flag */
> > +   li  r3, 0
> > +   stw r3, 0(r4)
> > +   b   fsl_deepsleep_resume
> > +11:
> > +#endif
> 
> Why do you come in via the normal kernel entry, versus specifying a
> direct entry point for deep sleep resume?  How does U-Boot even know
> what the normal entry is when resuming?

I wish to return to a specified point (like 64-bit mode), but the code in
fsl_booke_entry_mapping.S only can run in the first page. Because it
only setups a temp mapping of 4KB.

> 
> Be careful of the "beq s

Re: [PATCH 8/9] powerpc/85xx: add save/restore functions for core registers

2014-03-12 Thread Chenhui Zhao
On Tue, Mar 11, 2014 at 07:45:14PM -0500, Scott Wood wrote:
> On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > From: Wang Dongsheng 
> > 
> > Add booke_cpu_state_save() and booke_cpu_state_restore() functions which 
> > can be
> > used to save/restore CPU's registers in the case of deep sleep and 
> > hibernation.
> > 
> > Supported processors: E6500, E5500, E500MC, E500v2 and E500v1.
> > 
> > Signed-off-by: Wang Dongsheng 
> > Signed-off-by: Chenhui Zhao 
> > ---
> >  arch/powerpc/include/asm/booke_save_regs.h |   96 
> >  arch/powerpc/kernel/Makefile   |1 +
> >  arch/powerpc/kernel/booke_save_regs.S  |  361 
> > 
> >  3 files changed, 458 insertions(+), 0 deletions(-)
> >  create mode 100644 arch/powerpc/include/asm/booke_save_regs.h
> >  create mode 100644 arch/powerpc/kernel/booke_save_regs.S
> > 
> > diff --git a/arch/powerpc/include/asm/booke_save_regs.h 
> > b/arch/powerpc/include/asm/booke_save_regs.h
> > new file mode 100644
> > index 000..87c357a
> > --- /dev/null
> > +++ b/arch/powerpc/include/asm/booke_save_regs.h
> > @@ -0,0 +1,96 @@
> > +/*
> > + *  Save/restore e500 series core registers
> 
> Filename says booke, comment says e500.
> 
> Filename and comment also fail to point out that this is specifically
> for standby/suspend, not for hibernate which is implemented in
> swsusp_booke.S/swsusp_asm64.S.

Sorry for inconsistency. Will changes e500 to booke.
Hibernation and suspend can share the code.

> 
> > + *
> > + * Author: Wang Dongsheng 
> > + *
> > + * Copyright 2014 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 version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#ifndef __ASM_FSL_SLEEP_H
> > +#define __ASM_FSL_SLEEP_H
> > +
> > +/*
> > + * 8 bytes for each register, which is compatible with
> > + * both 32-bit and 64-bit registers
> > + *
> > + * Acronyms:
> > + * dw(data width)  0x08
> > + *
> > + * Map:
> > + * General-Purpose Registers
> > + * GPR1(sp)0
> > + * GPR20x8 (dw * 1)
> > + * GPR13 - GPR31   0x10 ~ 0xa0 (dw * 2 ~ dw * 20)
> 
> Putting these values in a comment separate from the code that defines it
> sounds like a good way to get a mismatch between the two.

Ok.

> 
> > + * Foating-point registers
> > + * FPR14 - FPR31   0xa8 ~ 0x130(dw * 21 ~ dw * 38)
> 
> Call enable_kernel_fp() or similar, rather than saving FP regs here.
> Likewise with altivec.  And why starting at FPR14?  Volatile versus
> nonvolatile is irrelevant because Linux doesn't participate in the FP
> ABI.  Everything is non-volatile *if* we have a user FP context
> resident, and everything is volatile otherwise.

Will remove them.

> 
> > + * Timer Registers
> > + * TCR 0x168   (dw * 45)
> > + * TB(64bit)   0x170   (dw * 46)
> > + * TBU(32bit)  0x178   (dw * 47)
> > + * TBL(32bit)  0x180   (dw * 48)
> 
> Why are you saving TBU/L separate from TB?  They're the same thing.

Will remove TBU and TBL.

> 
> > + * Interrupt Registers
> > + * IVPR0x188   (dw * 49)
> > + * IVOR0 - IVOR15  0x190 ~ 0x208   (dw * 50 ~ dw * 65)
> > + * IVOR32 - IVOR41 0x210 ~ 0x258   (dw * 66 ~ dw * 75)
> 
> What about IVOR42 (LRAT error)?

Will add it.

> 
> > + * Software-Use Registers
> > + * SPRG1   0x260   (dw * 76), 64-bit need to save.
> > + * SPRG3   0x268   (dw * 77), 32-bit need to save.
> 
> What about "CPU and NUMA node for VDSO getcpu" on 64-bit?  Currently
> SPRG3, but it will need to change for critical interrupt support.
> 
> > + * MMU Registers
> > + * PID0 - PID2 0x270 ~ 0x280   (dw * 78 ~ dw * 80)
> 
> PID1/PID2 are e500v1/v2 only -- and Linux doesn't use them outside of
> KVM (and you're not in KVM when you're running this code).
> 
> Are we ever going to have a non-zero PID at this point?

I incline to the view that saving all registers regardless of used or
unused. The good point is that it can be compliant to the future
changes of the usage of registers.

What do you think?

> 
> > + * Debug Registers
> > + * DBCR0 - DBCR2   0x288 ~ 0x298   (dw *

Re: [PATCH 7/9] fsl: add EPU FSM configuration for deep sleep

2014-03-12 Thread Chenhui Zhao
On Tue, Mar 11, 2014 at 07:08:43PM -0500, Scott Wood wrote:
> On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > From: Hongbo Zhang 
> > 
> > In the last stage of deep sleep, software will trigger a Finite
> > State Machine (FSM) to control the hardware precedure, such as
> > board isolation, killing PLLs, removing power, and so on.
> > 
> > When the system is waked up by an interrupt, the FSM controls the
> > hardware to complete the early resume precedure.
> > 
> > This patch configure the EPU FSM preparing for deep sleep.
> > 
> > Signed-off-by: Hongbo Zhang 
> > Signed-off-by: Chenhui Zhao 
> 
> Couldn't this be part of qoriq_pm.c?

Put the code in drivers/platform/fsl/ so that LS1 can share these code.

> 
> > diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
> > index 9b9a34a..eb83a30 100644
> > --- a/arch/powerpc/sysdev/fsl_soc.h
> > +++ b/arch/powerpc/sysdev/fsl_soc.h
> > @@ -69,5 +69,8 @@ extern const struct fsl_pm_ops *qoriq_pm_ops;
> >  
> >  extern int fsl_rcpm_init(void);
> >  
> > +extern void fsl_dp_fsm_setup(void *dcsr_base);
> > +extern void fsl_dp_fsm_clean(void *dcsr_base);
> 
> __iomem

Thanks. Will add.

> 
> > +
> >  #endif
> >  #endif
> > diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
> > index 09fde58..6539e6d 100644
> > --- a/drivers/platform/Kconfig
> > +++ b/drivers/platform/Kconfig
> > @@ -6,3 +6,7 @@ source "drivers/platform/goldfish/Kconfig"
> >  endif
> >  
> >  source "drivers/platform/chrome/Kconfig"
> > +
> > +if FSL_SOC
> > +source "drivers/platform/fsl/Kconfig"
> > +endif
> 
> Chrome doesn't need an ifdef -- why does this?

Don't wish other platform see these options, and the X86 and GOLDFISH have
ifdefs.

> 
> > diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
> > index 3656b7b..37c6f72 100644
> > --- a/drivers/platform/Makefile
> > +++ b/drivers/platform/Makefile
> > @@ -6,3 +6,4 @@ obj-$(CONFIG_X86)   += x86/
> >  obj-$(CONFIG_OLPC) += olpc/
> >  obj-$(CONFIG_GOLDFISH) += goldfish/
> >  obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
> > +obj-$(CONFIG_FSL_SOC)  += fsl/
> > diff --git a/drivers/platform/fsl/Kconfig b/drivers/platform/fsl/Kconfig
> > new file mode 100644
> > index 000..72ed053
> > --- /dev/null
> > +++ b/drivers/platform/fsl/Kconfig
> > @@ -0,0 +1,10 @@
> > +#
> > +# Freescale Specific Power Management Drivers
> > +#
> > +
> > +config FSL_SLEEP_FSM
> > +   bool
> > +   help
> > + This driver configures a hardware FSM (Finite State Machine) for deep 
> > sleep.
> > + The FSM is used to finish clean-ups at the last stage of system 
> > entering deep
> > + sleep, and also wakes up system when a wake up event happens.
> > diff --git a/drivers/platform/fsl/Makefile b/drivers/platform/fsl/Makefile
> > new file mode 100644
> > index 000..d99ca0e
> > --- /dev/null
> > +++ b/drivers/platform/fsl/Makefile
> > @@ -0,0 +1,5 @@
> > +#
> > +# Makefile for linux/drivers/platform/fsl
> > +# Freescale Specific Power Management Drivers
> > +#
> > +obj-$(CONFIG_FSL_SLEEP_FSM)+= sleep_fsm.o
> 
> Why is this here while the other stuff is in arch/powerpc/sysdev?
> 
> > +/* Block offsets */
> > +#defineRCPM_BLOCK_OFFSET   0x00022000
> > +#defineEPU_BLOCK_OFFSET0x
> > +#defineNPC_BLOCK_OFFSET0x1000
> 
> Why don't these block offsets come from the device tree?

Have maped DCSR registers. Don't wish to remap them.

> 
> > +static void *g_dcsr_base;
> 
> __iomem

OK.

> 
> > +   /* Configure the EPU Counters */
> > +   epu_write(EPCCR15, 0x9284);
> > +   epu_write(EPCCR14, 0x9284);
> > +   epu_write(EPCCR12, 0x9284);
> > +   epu_write(EPCCR11, 0x9284);
> > +   epu_write(EPCCR10, 0x9284);
> > +   epu_write(EPCCR9, 0x9284);
> > +   epu_write(EPCCR8, 0x9284);
> > +   epu_write(EPCCR5, 0x9284);
> > +   epu_write(EPCCR4, 0x9284);
> > +   epu_write(EPCCR2, 0x9284);
> > +
> > +   /* Configure the SCUs Inputs */
> > +   epu_write(EPSMCR15, 0x7600);
> > +   epu_write(EPSMCR14, 0x0031);
> > +   epu_write(EPSMCR13, 0x3100);
> > +   epu_write(EPSMCR12, 0x7F00);
> > +   epu_write(EPSMCR11, 0x3174);
> > +   epu_write(EPSMCR10, 0x6530);
> > 

Re: [PATCH 6/9] powerpc/85xx: support sleep feature on QorIQ SoCs with RCPM

2014-03-12 Thread Chenhui Zhao
On Tue, Mar 11, 2014 at 07:00:27PM -0500, Scott Wood wrote:
> On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > In sleep mode, the clocks of e500 cores and unused IP blocks is
> > turned off. The IP blocks which are allowed to wake up the processor
> > are still running.
> > 
> > The sleep mode is equal to the Standby state in Linux. Use the
> > command to enter sleep mode:
> >   echo standby > /sys/power/state
> > 
> > Signed-off-by: Chenhui Zhao 
> > ---
> >  arch/powerpc/Kconfig   |4 +-
> >  arch/powerpc/platforms/85xx/Makefile   |3 +
> >  arch/powerpc/platforms/85xx/qoriq_pm.c |   78 
> > 
> >  3 files changed, 83 insertions(+), 2 deletions(-)
> >  create mode 100644 arch/powerpc/platforms/85xx/qoriq_pm.c
> > 
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> > index 05f6323..e1d6510 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -222,7 +222,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
> > @@ -709,7 +709,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)
> 
> Don't mix && and || without parentheses.
> 
> Maybe convert this into being selected (similar to FSL_RCPM), rather
> than default y?

Yes, will do.

> 
> > diff --git a/arch/powerpc/platforms/85xx/Makefile 
> > b/arch/powerpc/platforms/85xx/Makefile
> > index 25cebe7..7fae817 100644
> > --- a/arch/powerpc/platforms/85xx/Makefile
> > +++ b/arch/powerpc/platforms/85xx/Makefile
> > @@ -2,6 +2,9 @@
> >  # Makefile for the PowerPC 85xx linux kernel.
> >  #
> >  obj-$(CONFIG_SMP) += smp.o
> > +ifeq ($(CONFIG_FSL_CORENET_RCPM), y)
> > +obj-$(CONFIG_SUSPEND)  += qoriq_pm.o
> > +endif
> 
> There should probably be a kconfig symbol for this.

OK.

> 
> > diff --git a/arch/powerpc/platforms/85xx/qoriq_pm.c 
> > b/arch/powerpc/platforms/85xx/qoriq_pm.c
> > new file mode 100644
> > index 000..915b13b
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/85xx/qoriq_pm.c
> > @@ -0,0 +1,78 @@
> > +/*
> > + * Support Power Management feature
> > + *
> > + * Copyright 2014 Freescale Semiconductor Inc.
> > + *
> > + * Author: Chenhui Zhao 
> > + *
> > + * This program is free software; you can redistribute it and/or 
> > modify it
> > + * under  the terms of the GNU General  Public License as published by 
> > the
> > + * Free Software Foundation;  either version 2 of the  License, or (at your
> > + * option) any later version.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +
> > +#define FSL_SLEEP  0x1
> > +#define FSL_DEEP_SLEEP 0x2
> 
> FSL_DEEP_SLEEP is unused.

Will be used in the last patch.
[PATCH 9/9] powerpc/pm: support deep sleep feature on T1040

> 
> > +
> > +/* specify the sleep state of the present platform */
> > +int sleep_pm_state;
> > +/* supported sleep modes by the present platform */
> > +static unsigned int sleep_modes;
> 
> Why is one signed and the other unsigned?

Undesigned. Will change them all to unsigned.

> 
> > +
> > +static int qoriq_suspend_enter(suspend_state_t state)
> > +{
> > +   int ret = 0;
> > +
> > +   switch (state) {
> > +   case PM_SUSPEND_STANDBY:
> > +
> > +   if (cur_cpu_spec->cpu_flush_caches)
> > +   cur_cpu_spec->cpu_flush_caches();
> > +
> > +   ret = qoriq_pm_ops->plat_enter_state(sleep_pm_state);
> > +
> > +   break;
> > +
> > +   default:
> > +   ret = -EINVAL;
> > +
> > +   }
> > +
> > +   return ret;
> > +}
> > +
> > +static int qoriq_suspend_valid(suspend_state_t state)
> > +{
> > +   if (state == PM_SUSPEND_STANDBY && (sleep_modes & FSL_SLEEP))
> > +   return 1;
> > +
> > +   return 0;
> > +}
> > +
> > +static const struct platf

Re: [PATCH 5/9] powerpc/85xx: disable irq by hardware when suspend for 64-bit

2014-03-12 Thread Chenhui Zhao
On Tue, Mar 11, 2014 at 06:51:20PM -0500, Scott Wood wrote:
> On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > In 64-bit mode, kernel just clears the irq soft-enable flag
> > in struct paca_struct to disable external irqs. But, in
> > the case of suspend, irqs should be disabled by hardware.
> > Therefore, hook a function to ppc_md.suspend_disable_irqs
> > to really disable irqs.
> > 
> > Signed-off-by: Chenhui Zhao 
> > ---
> >  arch/powerpc/platforms/85xx/corenet_generic.c |   12 
> >  1 files changed, 12 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c 
> > b/arch/powerpc/platforms/85xx/corenet_generic.c
> > index 3fdf9f3..983d81f 100644
> > --- a/arch/powerpc/platforms/85xx/corenet_generic.c
> > +++ b/arch/powerpc/platforms/85xx/corenet_generic.c
> > @@ -32,6 +32,13 @@
> >  #include 
> >  #include "smp.h"
> >  
> > +#if defined(CONFIG_PPC64) && defined(CONFIG_SUSPEND)
> > +static void fsl_suspend_disable_irqs(void)
> > +{
> > +   __hard_irq_disable();
> > +}
> > +#endif
> 
> Why the underscore version?  Don't you want PACA_IRQ_HARD_DIS to be set?
> 
> If hard disabling is appropriate here, shouldn't we do it in
> generic_suspend_disable_irqs()?
> 
> Are there any existing platforms that supply a
> ppc_md.suspend_disable_irqs()?  I don't see any when grepping.
> 
> -Scott

Will use hard_irq_disable().

I think this is a general problem for powerpc.
Should clear MSR_EE before suspend. I agree to put it
in generic_suspend_disable_irqs().

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/9] powerpc/85xx: support CPU hotplug for e500mc and e5500

2014-03-11 Thread Chenhui Zhao
On Tue, Mar 11, 2014 at 06:48:13PM -0500, Scott Wood wrote:
> On Fri, 2014-03-07 at 12:58 +0800, Chenhui Zhao wrote:
> > diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> > index ac2621a..f3f4401 100644
> > --- a/arch/powerpc/kernel/smp.c
> > +++ b/arch/powerpc/kernel/smp.c
> > @@ -405,8 +405,12 @@ void generic_cpu_die(unsigned int cpu)
> >  
> > for (i = 0; i < 100; i++) {
> > smp_rmb();
> > -   if (per_cpu(cpu_state, cpu) == CPU_DEAD)
> > +   if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
> > +#ifdef CONFIG_PPC64
> > +   paca[cpu].cpu_start = 0;
> > +#endif
> 
> Why wasn't this needed by previous ppc64 machines?

If not clear, cpu can't start in the case of cpu hotpolug.
The function pseries_cpu_die() in arch/powerpc/platforms/pseries/hotplug-cpu.c
also clears the flag.

> 
> > diff --git a/arch/powerpc/platforms/85xx/smp.c 
> > b/arch/powerpc/platforms/85xx/smp.c
> > index 2e5911e..0047883 100644
> > --- a/arch/powerpc/platforms/85xx/smp.c
> > +++ b/arch/powerpc/platforms/85xx/smp.c
> > @@ -19,6 +19,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #include 
> >  #include 
> > @@ -46,6 +47,17 @@ static u64 timebase;
> >  static int tb_req;
> >  static int tb_valid;
> >  
> > +#ifdef CONFIG_PPC_E500MC
> > +/* specify the cpu PM state when cpu dies, PH15/NAP is the default */
> > +int qoriq_cpu_die_state = E500_PM_PH15;
> > +#endif
> 
> static?  Is there any way to modify this other than modifying source
> code?
> 
> BTW, QorIQ doesn't imply an e500mc derivative.

Will support e500, but for now these code support e500mc derivative in
advance.

Supposed qoriq_cpu_die_state can be changed by platform init code
if the default value is not proper for a specific platform.

> 
> > @@ -125,6 +138,34 @@ static void mpc85xx_take_timebase(void)
> >  }
> >  
> >  #ifdef CONFIG_HOTPLUG_CPU
> > +#ifdef CONFIG_PPC_E500MC
> > +static void qoriq_cpu_die(void)
> > +{
> > +   unsigned int cpu = smp_processor_id();
> > +
> > +   local_irq_disable();
> > +#ifdef CONFIG_PPC64
> > +   __hard_irq_disable();
> > +#endif
> 
> Why this instead of one call to hard_irq_disable() (no leading
> underscores)?
> 
> -Scott

hard_irq_disable() will clear soft_enabled again. local_irq_disable()
has cleared it.

Will use hard_irq_disable() to replace these lines.

  local_irq_disable();
  #ifdef CONFIG_PPC64
__hard_irq_disable();
  #endif

-Chenhui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/9] powerpc/rcpm: add RCPM driver

2014-03-11 Thread Chenhui Zhao
On Tue, Mar 11, 2014 at 06:42:51PM -0500, Scott Wood wrote:
> On Fri, 2014-03-07 at 12:57 +0800, Chenhui Zhao wrote:
> > diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c 
> > b/arch/powerpc/platforms/85xx/corenet_generic.c
> > index b756f3d..3fdf9f3 100644
> > --- a/arch/powerpc/platforms/85xx/corenet_generic.c
> > +++ b/arch/powerpc/platforms/85xx/corenet_generic.c
> > @@ -56,6 +56,8 @@ void __init corenet_gen_setup_arch(void)
> >  
> > swiotlb_detect_4g();
> >  
> > +   fsl_rcpm_init();
> > +
> > pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
> 
> RCPM is not board-specific.  Why is this in board code?

Init the RCPM driver in the early stage before smp_init(). Because
the time base sync calls a callback function .freeze_time_base()
in the RCPM driver.

Will use early_initcall() instead.

> 
> > +static void rcpm_v1_cpu_enter_state(int cpu, int state)
> > +{
> > +   unsigned int hw_cpu = get_hard_smp_processor_id(cpu);
> > +   unsigned int mask = 1 << hw_cpu;
> > +
> > +   switch (state) {
> > +   case E500_PM_PH10:
> > +   setbits32(&rcpm_v1_regs->cdozcr, mask);
> > +   break;
> > +   case E500_PM_PH15:
> > +   setbits32(&rcpm_v1_regs->cnapcr, mask);
> > +   break;
> > +   default:
> > +   pr_err("Unknown cpu PM state\n");
> > +   break;
> > +   }
> > +}
> 
> Put __func__ in error messages -- and for "unknown value" type messages,
> print the value.

OK.

> 
> 
> > +static int rcpm_v1_plat_enter_state(int state)
> > +{
> > +   u32 *pmcsr_reg = &rcpm_v1_regs->powmgtcsr;
> > +   int ret = 0;
> > +   int result;
> > +
> > +   switch (state) {
> > +   case PLAT_PM_SLEEP:
> > +   setbits32(pmcsr_reg, RCPM_POWMGTCSR_SLP);
> > +
> > +   /* At this point, the device is in sleep mode. */
> > +
> > +   /* Upon resume, wait for RCPM_POWMGTCSR_SLP bit to be clear. */
> > +   result = spin_event_timeout(
> > + !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_SLP), 1, 10);
> > +   if (!result) {
> > +   pr_err("%s: timeout waiting for SLP bit to be 
> > cleared\n",
> > + __func__);
> 
> Why are you indenting continuation lines with only two spaces (and yet
> still not aligning with anything)?

Will align with the previous parenthesis.

> 
> > +   ret = -ETIMEDOUT;
> > +   }
> > +   break;
> > +   default:
> > +   pr_err("Unsupported platform PM state\n");
> > +   ret = -EINVAL;
> > +   }
> > +
> > +   return ret;
> > +}
> > +
> > +static void rcpm_v1_freeze_time_base(int freeze)
> > +{
> > +   u32 *tben_reg = &rcpm_v1_regs->ctbenr;
> > +   static u32 mask;
> > +
> > +   if (freeze) {
> > +   mask = in_be32(tben_reg);
> > +   clrbits32(tben_reg, mask);
> > +   } else {
> > +   setbits32(tben_reg, mask);
> > +   }
> > +
> > +   /* read back to push the previous write */
> > +   in_be32(tben_reg);
> > +}
> > +
> > +static void rcpm_v2_freeze_time_base(int freeze)
> > +{
> > +   u32 *tben_reg = &rcpm_v2_regs->pctbenr;
> > +   static u32 mask;
> > +
> > +   if (freeze) {
> > +   mask = in_be32(tben_reg);
> > +   clrbits32(tben_reg, mask);
> > +   } else {
> > +   setbits32(tben_reg, mask);
> > +   }
> > +
> > +   /* read back to push the previous write */
> > +   in_be32(tben_reg);
> > +}
> 
> It looks like the only difference between these two functions is how you
> calculate tben_reg -- factor the rest out into a single function.

Yes. Will factor them out into a single function.

> 
> > +int fsl_rcpm_init(void)
> > +{
> > +   struct device_node *np;
> > +
> > +   np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-rcpm-2.0");
> > +   if (np) {
> > +   rcpm_v2_regs = of_iomap(np, 0);
> > +   of_node_put(np);
> > +   if (!rcpm_v2_regs)
> > +   return -ENOMEM;
> > +
> > +   qoriq_pm_ops = &qoriq_rcpm_v2_ops;
> > +
> > +   } else {
> > +   np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-rcpm-1.0");
> > +   if (np) {
> > +   rcpm_v1_regs = of_iomap(np, 0);
> > +

[PATCH 6/9] powerpc/85xx: support sleep feature on QorIQ SoCs with RCPM

2014-03-06 Thread Chenhui Zhao
In sleep mode, the clocks of e500 cores and unused IP blocks is
turned off. The IP blocks which are allowed to wake up the processor
are still running.

The sleep mode is equal to the Standby state in Linux. Use the
command to enter sleep mode:
  echo standby > /sys/power/state

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/Kconfig   |4 +-
 arch/powerpc/platforms/85xx/Makefile   |3 +
 arch/powerpc/platforms/85xx/qoriq_pm.c |   78 
 3 files changed, 83 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/qoriq_pm.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 05f6323..e1d6510 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -222,7 +222,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
@@ -709,7 +709,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/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index 25cebe7..7fae817 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -2,6 +2,9 @@
 # Makefile for the PowerPC 85xx linux kernel.
 #
 obj-$(CONFIG_SMP) += smp.o
+ifeq ($(CONFIG_FSL_CORENET_RCPM), y)
+obj-$(CONFIG_SUSPEND)  += qoriq_pm.o
+endif
 
 obj-y += common.o
 
diff --git a/arch/powerpc/platforms/85xx/qoriq_pm.c 
b/arch/powerpc/platforms/85xx/qoriq_pm.c
new file mode 100644
index 000..915b13b
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/qoriq_pm.c
@@ -0,0 +1,78 @@
+/*
+ * Support Power Management feature
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * Author: Chenhui Zhao 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#define FSL_SLEEP  0x1
+#define FSL_DEEP_SLEEP 0x2
+
+/* specify the sleep state of the present platform */
+int sleep_pm_state;
+/* supported sleep modes by the present platform */
+static unsigned int sleep_modes;
+
+static int qoriq_suspend_enter(suspend_state_t state)
+{
+   int ret = 0;
+
+   switch (state) {
+   case PM_SUSPEND_STANDBY:
+
+   if (cur_cpu_spec->cpu_flush_caches)
+   cur_cpu_spec->cpu_flush_caches();
+
+   ret = qoriq_pm_ops->plat_enter_state(sleep_pm_state);
+
+   break;
+
+   default:
+   ret = -EINVAL;
+
+   }
+
+   return ret;
+}
+
+static int qoriq_suspend_valid(suspend_state_t state)
+{
+   if (state == PM_SUSPEND_STANDBY && (sleep_modes & FSL_SLEEP))
+   return 1;
+
+   return 0;
+}
+
+static const struct platform_suspend_ops qoriq_suspend_ops = {
+   .valid = qoriq_suspend_valid,
+   .enter = qoriq_suspend_enter,
+};
+
+static int __init qoriq_suspend_init(void)
+{
+   struct device_node *np;
+
+   sleep_modes = FSL_SLEEP;
+   sleep_pm_state = PLAT_PM_SLEEP;
+
+   np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-rcpm-2.0");
+   if (np)
+   sleep_pm_state = PLAT_PM_LPM20;
+
+   suspend_set_ops(&qoriq_suspend_ops);
+
+   return 0;
+}
+arch_initcall(qoriq_suspend_init);
-- 
1.7.3


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 9/9] powerpc/pm: support deep sleep feature on T1040

2014-03-06 Thread Chenhui Zhao
From: Zhao Chenhui 

T1040 supports deep sleep feature, which can switch off most parts of
the SoC when it is in deep sleep mode. This way, it becomes more
energy-efficient.

The DDR controller will also be powered off in deep sleep. Therefore,
the last stage (the latter part of fsl_dp_enter_low) will run without DDR
access. This piece of code and related TLBs will be prefetched.

Due to the different initialization code between 32-bit and 64-bit, they
have seperate resume entry and precedure.

The feature supports 32-bit and 64-bit kernel mode.

Signed-off-by: Zhao Chenhui 
---
 arch/powerpc/include/asm/booke_save_regs.h |3 +
 arch/powerpc/kernel/cpu_setup_fsl_booke.S  |   17 ++
 arch/powerpc/kernel/head_fsl_booke.S   |   30 +++
 arch/powerpc/platforms/85xx/Makefile   |2 +-
 arch/powerpc/platforms/85xx/deepsleep.c|  201 +++
 arch/powerpc/platforms/85xx/qoriq_pm.c |   38 
 arch/powerpc/platforms/85xx/sleep.S|  295 
 arch/powerpc/sysdev/fsl_soc.h  |7 +
 8 files changed, 592 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/deepsleep.c
 create mode 100644 arch/powerpc/platforms/85xx/sleep.S

diff --git a/arch/powerpc/include/asm/booke_save_regs.h 
b/arch/powerpc/include/asm/booke_save_regs.h
index 87c357a..37c1f6c 100644
--- a/arch/powerpc/include/asm/booke_save_regs.h
+++ b/arch/powerpc/include/asm/booke_save_regs.h
@@ -88,6 +88,9 @@
 #define HIBERNATION_FLAG   1
 #define DEEPSLEEP_FLAG 2
 
+#define CPLD_FLAG  1
+#define FPGA_FLAG  2
+
 #ifndef __ASSEMBLY__
 extern void booke_cpu_state_save(void *buf, int type);
 extern void *booke_cpu_state_restore(void *buf, int type);
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S 
b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index e59d6de..ea9bc28 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -318,6 +318,23 @@ flush_backside_L2_cache:
 2:
blr
 
+#define CPC_CPCCSR00x0
+#define CPC_CPCCSR0_CPCFL  0x800
+
+/* r3 : the base address of CPC  */
+_GLOBAL(fsl_flush_cpc_cache)
+   lwz r6, CPC_CPCCSR0(r3)
+   ori r6, r6, CPC_CPCCSR0_CPCFL
+   stw r6, CPC_CPCCSR0(r3)
+   sync
+
+   /* Wait until completing the flush */
+1: lwz r6, CPC_CPCCSR0(r3)
+   andi.   r6, r6, CPC_CPCCSR0_CPCFL
+   bne 1b
+
+   blr
+
 _GLOBAL(__flush_caches_e500v2)
mflr r0
bl  flush_dcache_L1
diff --git a/arch/powerpc/kernel/head_fsl_booke.S 
b/arch/powerpc/kernel/head_fsl_booke.S
index 20204fe..3285752 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -162,6 +162,19 @@ _ENTRY(__early_start)
 #include "fsl_booke_entry_mapping.S"
 #undef ENTRY_MAPPING_BOOT_SETUP
 
+#if defined(CONFIG_SUSPEND) && defined(CONFIG_FSL_CORENET_RCPM)
+   /* if deep_sleep_flag != 0, jump to the deep sleep resume entry */
+   LOAD_REG_ADDR(r4, deep_sleep_flag)
+   lwz r3, 0(r4)
+   cmpwi   r3, 0
+   beq 11f
+   /* clear deep_sleep_flag */
+   li  r3, 0
+   stw r3, 0(r4)
+   b   fsl_deepsleep_resume
+11:
+#endif
+
 set_ivor:
/* Establish the interrupt vector offsets */
SET_IVOR(0,  CriticalInput);
@@ -343,6 +356,23 @@ set_ivor:
lwz r11, 0(r12);/* Get Linux PTE */
 #endif
 
+#if defined(CONFIG_SUSPEND) && defined(CONFIG_FSL_CORENET_RCPM)
+_ENTRY(__entry_deep_sleep)
+/*
+ * Bootloader will jump to here when resuming from deep sleep.
+ * After executing the init code in fsl_booke_entry_mapping.S,
+ * will jump to the real resume entry.
+ */
+   li  r8, 1
+   bl  12f
+12:mflrr9
+   addir9, r9, (deep_sleep_flag - 12b)
+   stw r8, 0(r9)
+   b __early_start
+deep_sleep_flag:
+   .long   0
+#endif
+
 /*
  * Interrupt vector entry code
  *
diff --git a/arch/powerpc/platforms/85xx/Makefile 
b/arch/powerpc/platforms/85xx/Makefile
index 7fae817..9a4ea86 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -3,7 +3,7 @@
 #
 obj-$(CONFIG_SMP) += smp.o
 ifeq ($(CONFIG_FSL_CORENET_RCPM), y)
-obj-$(CONFIG_SUSPEND)  += qoriq_pm.o
+obj-$(CONFIG_SUSPEND)  += qoriq_pm.o deepsleep.o sleep.o
 endif
 
 obj-y += common.o
diff --git a/arch/powerpc/platforms/85xx/deepsleep.c 
b/arch/powerpc/platforms/85xx/deepsleep.c
new file mode 100644
index 000..ddd7185
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/deepsleep.c
@@ -0,0 +1,201 @@
+/*
+ * Support deep sleep feature
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * Author: Chenhui Zhao 
+ *
+ * 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

[PATCH 7/9] fsl: add EPU FSM configuration for deep sleep

2014-03-06 Thread Chenhui Zhao
From: Hongbo Zhang 

In the last stage of deep sleep, software will trigger a Finite
State Machine (FSM) to control the hardware precedure, such as
board isolation, killing PLLs, removing power, and so on.

When the system is waked up by an interrupt, the FSM controls the
hardware to complete the early resume precedure.

This patch configure the EPU FSM preparing for deep sleep.

Signed-off-by: Hongbo Zhang 
Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/platforms/85xx/Kconfig |1 +
 arch/powerpc/sysdev/fsl_soc.h   |3 +
 drivers/platform/Kconfig|4 +
 drivers/platform/Makefile   |1 +
 drivers/platform/fsl/Kconfig|   10 +
 drivers/platform/fsl/Makefile   |5 +
 drivers/platform/fsl/sleep_fsm.c|  415 +++
 7 files changed, 439 insertions(+), 0 deletions(-)
 create mode 100644 drivers/platform/fsl/Kconfig
 create mode 100644 drivers/platform/fsl/Makefile
 create mode 100644 drivers/platform/fsl/sleep_fsm.c

diff --git a/arch/powerpc/platforms/85xx/Kconfig 
b/arch/powerpc/platforms/85xx/Kconfig
index 54d8843..27e2174 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -261,6 +261,7 @@ config CORENET_GENERIC
select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
+   select FSL_SLEEP_FSM if SUSPEND
help
  This option enables support for the FSL CoreNet based boards.
  For 32bit kernel, the following boards are supported:
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 9b9a34a..eb83a30 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -69,5 +69,8 @@ extern const struct fsl_pm_ops *qoriq_pm_ops;
 
 extern int fsl_rcpm_init(void);
 
+extern void fsl_dp_fsm_setup(void *dcsr_base);
+extern void fsl_dp_fsm_clean(void *dcsr_base);
+
 #endif
 #endif
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 09fde58..6539e6d 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -6,3 +6,7 @@ source "drivers/platform/goldfish/Kconfig"
 endif
 
 source "drivers/platform/chrome/Kconfig"
+
+if FSL_SOC
+source "drivers/platform/fsl/Kconfig"
+endif
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index 3656b7b..37c6f72 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_X86)   += x86/
 obj-$(CONFIG_OLPC) += olpc/
 obj-$(CONFIG_GOLDFISH) += goldfish/
 obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
+obj-$(CONFIG_FSL_SOC)  += fsl/
diff --git a/drivers/platform/fsl/Kconfig b/drivers/platform/fsl/Kconfig
new file mode 100644
index 000..72ed053
--- /dev/null
+++ b/drivers/platform/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale Specific Power Management Drivers
+#
+
+config FSL_SLEEP_FSM
+   bool
+   help
+ This driver configures a hardware FSM (Finite State Machine) for deep 
sleep.
+ The FSM is used to finish clean-ups at the last stage of system 
entering deep
+ sleep, and also wakes up system when a wake up event happens.
diff --git a/drivers/platform/fsl/Makefile b/drivers/platform/fsl/Makefile
new file mode 100644
index 000..d99ca0e
--- /dev/null
+++ b/drivers/platform/fsl/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/fsl
+# Freescale Specific Power Management Drivers
+#
+obj-$(CONFIG_FSL_SLEEP_FSM)+= sleep_fsm.o
diff --git a/drivers/platform/fsl/sleep_fsm.c b/drivers/platform/fsl/sleep_fsm.c
new file mode 100644
index 000..102
--- /dev/null
+++ b/drivers/platform/fsl/sleep_fsm.c
@@ -0,0 +1,415 @@
+/*
+ * Freescale deep sleep FSM (finite-state machine) configuration
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * Author: Hongbo Zhang 
+ * Chenhui Zhao 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+
+#define FSL_STRIDE_4B  4
+#define FSL_STRIDE_8B  8
+
+/* Event Processor Global Control Register */
+#defineEPGCR   0x000
+
+/* Event Processor EVT Pin Control Registers */
+#defineEPEVTCR00x050
+#defineEPEVTCR10x054
+#defineEPEVTCR20x058
+#defineEPEVTCR30x05C
+#defineEPEVTCR40x060
+#defineEPEVTCR50x064
+#defineEPEVTCR60x068
+#defineEPEVTCR70x06C
+#defineEPEVTCR80x070
+#defineEPEVTCR90x074
+
+/* Event Processor Crosstrigger Control Register */
+#defineEPXTRIGCR   0x090
+
+/* Event Processor Input Mux Control Registers */
+#defineEPIMCR0 0x100
+#defineEPIMCR1 0x104
+#defin

[PATCH 5/9] powerpc/85xx: disable irq by hardware when suspend for 64-bit

2014-03-06 Thread Chenhui Zhao
In 64-bit mode, kernel just clears the irq soft-enable flag
in struct paca_struct to disable external irqs. But, in
the case of suspend, irqs should be disabled by hardware.
Therefore, hook a function to ppc_md.suspend_disable_irqs
to really disable irqs.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/platforms/85xx/corenet_generic.c |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c 
b/arch/powerpc/platforms/85xx/corenet_generic.c
index 3fdf9f3..983d81f 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -32,6 +32,13 @@
 #include 
 #include "smp.h"
 
+#if defined(CONFIG_PPC64) && defined(CONFIG_SUSPEND)
+static void fsl_suspend_disable_irqs(void)
+{
+   __hard_irq_disable();
+}
+#endif
+
 void __init corenet_gen_pic_init(void)
 {
struct mpic *mpic;
@@ -58,6 +65,11 @@ void __init corenet_gen_setup_arch(void)
 
fsl_rcpm_init();
 
+#if defined(CONFIG_PPC64) && defined(CONFIG_SUSPEND)
+   /* physically disable irq for 64-bit mode when suspend */
+   ppc_md.suspend_disable_irqs = fsl_suspend_disable_irqs;
+#endif
+
pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
 }
 
-- 
1.7.3


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/9] powerpc/cache: add cache flush operation for various e500

2014-03-06 Thread Chenhui Zhao
Various e500 core have different cache architecture, so they
need different cache flush operations. Therefore, add a callback
function cpu_flush_caches to the struct cpu_spec. The cache flush
operation for the specific kind of e500 is selected at init time.
The callback function will flush all caches in the current cpu.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/include/asm/cacheflush.h |2 -
 arch/powerpc/include/asm/cputable.h   |   11 +++
 arch/powerpc/kernel/asm-offsets.c |3 +
 arch/powerpc/kernel/cpu_setup_fsl_booke.S |  114 -
 arch/powerpc/kernel/cputable.c|4 +
 arch/powerpc/kernel/head_fsl_booke.S  |   74 ---
 arch/powerpc/platforms/85xx/smp.c |4 +-
 7 files changed, 134 insertions(+), 78 deletions(-)

diff --git a/arch/powerpc/include/asm/cacheflush.h 
b/arch/powerpc/include/asm/cacheflush.h
index 5b93122..039753e 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -30,8 +30,6 @@ 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);
 extern void flush_icache_user_range(struct vm_area_struct *vma,
struct page *page, unsigned long addr,
diff --git a/arch/powerpc/include/asm/cputable.h 
b/arch/powerpc/include/asm/cputable.h
index 617cc76..2c497a2 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -43,6 +43,13 @@ extern int machine_check_e500(struct pt_regs *regs);
 extern int machine_check_e200(struct pt_regs *regs);
 extern int machine_check_47x(struct pt_regs *regs);
 
+#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC)
+extern void __flush_caches_e500v2(void);
+extern void __flush_caches_e500mc(void);
+extern void __flush_caches_e5500(void);
+extern void __flush_caches_e6500(void);
+#endif
+
 /* NOTE WELL: Update identify_cpu() if fields are added or removed! */
 struct cpu_spec {
/* CPU is matched via (PVR & pvr_mask) == pvr_value */
@@ -59,6 +66,10 @@ struct cpu_spec {
unsigned inticache_bsize;
unsigned intdcache_bsize;
 
+#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC)
+   /* flush caches of the cpu which is running the function */
+   void (*cpu_flush_caches)(void);
+#endif
/* number of performance monitor counters */
unsigned intnum_pmcs;
enum powerpc_pmc_type pmc_type;
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 8d1d94d..5157fb4 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -372,6 +372,9 @@ int main(void)
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
+#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC)
+   DEFINE(CPU_FLUSH_CACHES, offsetof(struct cpu_spec, cpu_flush_caches));
+#endif
 
DEFINE(pbe_address, offsetof(struct pbe, address));
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S 
b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index cc2d896..e59d6de 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -1,7 +1,7 @@
 /*
  * This file contains low level CPU setup functions.
  * Kumar Gala 
- * Copyright 2009 Freescale Semiconductor, Inc.
+ * Copyright 2009, 2014 Freescale Semiconductor, Inc.
  *
  * Based on cpu_setup_6xx code by
  * Benjamin Herrenschmidt 
@@ -13,11 +13,13 @@
  *
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 _GLOBAL(__e500_icache_setup)
mfspr   r0, SPRN_L1CSR1
@@ -223,3 +225,113 @@ _GLOBAL(__setup_cpu_e5500)
mtlrr5
blr
 #endif
+
+/* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */
+_GLOBAL(flush_dcache_L1)
+   mfmsr   r10
+   wrteei  0
+
+   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

[PATCH 4/9] powerpc/85xx: support CPU hotplug for e500mc and e5500

2014-03-06 Thread Chenhui Zhao
Implemented CPU hotplug on e500mc and e5500. On e5500 both 32-bit and
64-bit modes can work. Used some callback functions implemented in RCPM
driver.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/Kconfig  |2 +-
 arch/powerpc/kernel/smp.c |6 ++-
 arch/powerpc/mm/tlb_nohash.c  |6 ++-
 arch/powerpc/platforms/85xx/smp.c |   94 ++---
 4 files changed, 87 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a5e5d2e..05f6323 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -362,7 +362,7 @@ config SWIOTLB
 config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
depends on SMP && (PPC_PSERIES || \
-   PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
+   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 ac2621a..f3f4401 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -405,8 +405,12 @@ void generic_cpu_die(unsigned int cpu)
 
for (i = 0; i < 100; i++) {
smp_rmb();
-   if (per_cpu(cpu_state, cpu) == CPU_DEAD)
+   if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
+#ifdef CONFIG_PPC64
+   paca[cpu].cpu_start = 0;
+#endif
return;
+   }
msleep(100);
}
printk(KERN_ERR "CPU%d didn't die...\n", cpu);
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index b37a58e..d24e06c 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -648,8 +648,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);
+   }
 
if (book3e_htw_mode == PPC_HTW_NONE) {
patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
diff --git a/arch/powerpc/platforms/85xx/smp.c 
b/arch/powerpc/platforms/85xx/smp.c
index 2e5911e..0047883 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -46,6 +47,17 @@ static u64 timebase;
 static int tb_req;
 static int tb_valid;
 
+#ifdef CONFIG_PPC_E500MC
+/* specify the cpu PM state when cpu dies, PH15/NAP is the default */
+int qoriq_cpu_die_state = E500_PM_PH15;
+#endif
+
+#ifdef CONFIG_PPC_E500MC
+static void mpc85xx_timebase_freeze(int freeze)
+{
+   qoriq_pm_ops->freeze_time_base(freeze);
+}
+#else
 static void mpc85xx_timebase_freeze(int freeze)
 {
uint32_t mask;
@@ -58,6 +70,7 @@ static void mpc85xx_timebase_freeze(int freeze)
 
in_be32(&guts->devdisr);
 }
+#endif
 
 static void mpc85xx_give_timebase(void)
 {
@@ -125,6 +138,34 @@ static void mpc85xx_take_timebase(void)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
+#ifdef CONFIG_PPC_E500MC
+static void qoriq_cpu_die(void)
+{
+   unsigned int cpu = smp_processor_id();
+
+   local_irq_disable();
+#ifdef CONFIG_PPC64
+   __hard_irq_disable();
+#endif
+   idle_task_exit();
+
+   if (qoriq_pm_ops->irq_mask)
+   qoriq_pm_ops->irq_mask(cpu);
+
+   mtspr(SPRN_TCR, 0);
+   mtspr(SPRN_TSR, mfspr(SPRN_TSR));
+
+   generic_set_cpu_dead(cpu);
+
+   if (cur_cpu_spec && cur_cpu_spec->cpu_flush_caches)
+   cur_cpu_spec->cpu_flush_caches();
+
+   qoriq_pm_ops->cpu_enter_state(cpu, qoriq_cpu_die_state);
+
+   while (1)
+   ;
+}
+#else
 static void smp_85xx_mach_cpu_die(void)
 {
unsigned int cpu = smp_processor_id();
@@ -155,6 +196,7 @@ static void smp_85xx_mach_cpu_die(void)
;
 }
 #endif
+#endif
 
 static inline void flush_spin_table(void *spin_table)
 {
@@ -208,11 +250,8 @@ static int 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);
 
+#ifdef CONFIG_HOTPLUG_CPU
if (system_state == SYSTEM_RUNNING) {
/*
 * To keep it compatible with old boot program which uses
@@ -225,6 +264,12 @@ static int smp_85xx_kick_cpu(int nr)
out_be32(&spin_table->addr_l, 0);
flush_

[PATCH 8/9] powerpc/85xx: add save/restore functions for core registers

2014-03-06 Thread Chenhui Zhao
From: Wang Dongsheng 

Add booke_cpu_state_save() and booke_cpu_state_restore() functions which can be
used to save/restore CPU's registers in the case of deep sleep and hibernation.

Supported processors: E6500, E5500, E500MC, E500v2 and E500v1.

Signed-off-by: Wang Dongsheng 
Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/include/asm/booke_save_regs.h |   96 
 arch/powerpc/kernel/Makefile   |1 +
 arch/powerpc/kernel/booke_save_regs.S  |  361 
 3 files changed, 458 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/include/asm/booke_save_regs.h
 create mode 100644 arch/powerpc/kernel/booke_save_regs.S

diff --git a/arch/powerpc/include/asm/booke_save_regs.h 
b/arch/powerpc/include/asm/booke_save_regs.h
new file mode 100644
index 000..87c357a
--- /dev/null
+++ b/arch/powerpc/include/asm/booke_save_regs.h
@@ -0,0 +1,96 @@
+/*
+ *  Save/restore e500 series core registers
+ *
+ * Author: Wang Dongsheng 
+ *
+ * Copyright 2014 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_FSL_SLEEP_H
+#define __ASM_FSL_SLEEP_H
+
+/*
+ * 8 bytes for each register, which is compatible with
+ * both 32-bit and 64-bit registers
+ *
+ * Acronyms:
+ * dw(data width)  0x08
+ *
+ * Map:
+ * General-Purpose Registers
+ * GPR1(sp)0
+ * GPR20x8 (dw * 1)
+ * GPR13 - GPR31   0x10 ~ 0xa0 (dw * 2 ~ dw * 20)
+ * Foating-point registers
+ * FPR14 - FPR31   0xa8 ~ 0x130(dw * 21 ~ dw * 38)
+ * Registers for Branch Operations
+ * CR  0x138   (dw * 39)
+ * LR  0x140   (dw * 40)
+ * Processor Control Registers
+ * MSR 0x148   (dw * 41)
+ * EPCR0x150   (dw * 42)
+ *
+ * Only e500, e500v2 need to save HID0 - HID1
+ * HID0 - HID1 0x158 ~ 0x160 (dw * 43 ~ dw * 44)
+ * Timer Registers
+ * TCR 0x168   (dw * 45)
+ * TB(64bit)   0x170   (dw * 46)
+ * TBU(32bit)  0x178   (dw * 47)
+ * TBL(32bit)  0x180   (dw * 48)
+ * Interrupt Registers
+ * IVPR0x188   (dw * 49)
+ * IVOR0 - IVOR15  0x190 ~ 0x208   (dw * 50 ~ dw * 65)
+ * IVOR32 - IVOR41 0x210 ~ 0x258   (dw * 66 ~ dw * 75)
+ * Software-Use Registers
+ * SPRG1   0x260   (dw * 76), 64-bit need to save.
+ * SPRG3   0x268   (dw * 77), 32-bit need to save.
+ * MMU Registers
+ * PID0 - PID2 0x270 ~ 0x280   (dw * 78 ~ dw * 80)
+ * Debug Registers
+ * DBCR0 - DBCR2   0x288 ~ 0x298   (dw * 81 ~ dw * 83)
+ * IAC1 - IAC4 0x2a0 ~ 0x2b8   (dw * 84 ~ dw * 87)
+ * DAC1 - DAC2 0x2c0 ~ 0x2c8   (dw * 88 ~ dw * 89)
+ *
+ */
+
+#define SR_GPR10x000
+#define SR_GPR20x008
+#define SR_GPR13   0x010
+#define SR_FPR14   0x0a8
+#define SR_CR  0x138
+#define SR_LR  0x140
+#define SR_MSR 0x148
+#define SR_EPCR0x150
+#define SR_HID00x158
+#define SR_TCR 0x168
+#define SR_TB  0x170
+#define SR_TBU 0x178
+#define SR_TBL 0x180
+#define SR_IVPR0x188
+#define SR_IVOR0   0x190
+#define SR_IVOR32  0x210
+#define SR_SPRG1   0x260
+#define SR_SPRG3   0x268
+#define SR_PID00x270
+#define SR_DBCR0   0x288
+#define SR_IAC10x2a0
+#define SR_DAC10x2c0
+#define REGS_BUFFER_SIZE   (SR_DAC1 + 0x10)
+
+/*
+ * hibernation and deepsleep save/restore different number of registers,
+ * use these flags to indicate.
+ */
+#define HIBERNATION_FLAG   1
+#define DEEPSLEEP_FLAG 2
+
+#ifndef __ASSEMBLY__
+extern void booke_cpu_state_save(void *buf, int type);
+extern void *booke_cpu_state_restore(void *buf, int type);
+#endif
+#endif
+
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index fcc9a89..64acae6 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_HIBERNATION) += swsusp_booke.o
 else
 obj-$(CONFIG_HIBERNATION)  += swsusp_$(CONFIG_WORD_SIZE).o
 endif
+obj-$(CONFIG_E500) += booke_save_regs.o
 obj64-$(CONFIG_HIBERNATION)+= swsusp_asm64.o
 obj-$(CONFIG_MODULES)  += module.o module_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_44x)  += cpu_setup_44x.o
diff --git a/arch/po

[PATCH 1/9] powerpc/fsl: add PVR definition for E500MC and E5500

2014-03-06 Thread Chenhui Zhao
From: Wang Dongsheng 

Signed-off-by: Wang Dongsheng 
---
 arch/powerpc/include/asm/reg.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 62b114e..cd7b630 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1075,6 +1075,8 @@
 #define PVR_8560   0x8020
 #define PVR_VER_E500V1 0x8020
 #define PVR_VER_E500V2 0x8021
+#define PVR_VER_E500MC 0x8023
+#define PVR_VER_E5500  0x8024
 #define PVR_VER_E6500  0x8040
 
 /*
-- 
1.7.3


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/9] powerpc/rcpm: add RCPM driver

2014-03-06 Thread Chenhui Zhao
There is a RCPM (Run Control/Power Management) in Freescale QorIQ
series processors. The device performs tasks associated with device
run control and power management.

The driver implements some features: mask/unmask irq, enter/exit low
power states, freeze time base, etc.

There are two versions of register map in RCPM, which is specified by
the compatible entry in the RCPM node of device tree.

Signed-off-by: Chenhui Zhao 
---
 arch/powerpc/include/asm/fsl_guts.h   |  105 
 arch/powerpc/platforms/85xx/Kconfig   |1 +
 arch/powerpc/platforms/85xx/corenet_generic.c |2 +
 arch/powerpc/sysdev/Kconfig   |5 +
 arch/powerpc/sysdev/Makefile  |1 +
 arch/powerpc/sysdev/fsl_rcpm.c|  315 +
 arch/powerpc/sysdev/fsl_soc.h |   24 ++
 7 files changed, 453 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/sysdev/fsl_rcpm.c

diff --git a/arch/powerpc/include/asm/fsl_guts.h 
b/arch/powerpc/include/asm/fsl_guts.h
index 77ced0b..492534a 100644
--- a/arch/powerpc/include/asm/fsl_guts.h
+++ b/arch/powerpc/include/asm/fsl_guts.h
@@ -185,5 +185,110 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts 
__iomem *guts,
 
 #endif
 
+struct ccsr_rcpm_v1 {
+   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 */
+#define RCPM_POWMGTCSR_SLP 0x0002
+   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 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_RQ0x