ARM: mx3: Let mx31 and mx35 enter in LPM mode in WFI
authorFabio Estevam <festevam@gmail.com>
Thu, 2 Feb 2012 22:02:32 +0000 (20:02 -0200)
committerSascha Hauer <s.hauer@pengutronix.de>
Fri, 2 Mar 2012 07:47:49 +0000 (08:47 +0100)
The LPM field of register CCMR is used to select the mode that the processor will run
when it goes to WFI.

When mx31 enters in WFI mode the LPM field is at its reset value of 0,
which configures the mx31 to enter in "wait mode".

On mx35, the LPM field on mx35 is also at 0 after reset, which corresponds
to "run mode" instead of "wait mode".

Instead of relying on the reset value of LPM to set the low power mode for
WFI, configure mx31 and mx35 to run in "wait mode"

Reported-by: Benoit Thebaudeau <benoit.thebaudeau@advansee.com>
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/crmregs-imx31.h
arch/arm/mach-imx/mm-imx3.c
arch/arm/mach-imx/pm-imx3.c [new file with mode: 0644]
arch/arm/plat-mxc/include/mach/common.h

index 55db9c488f2b408162e4bcca36f44d7cdb444ac0..f4b6fb0730cb6144bdcdb269f9267cbbc58ded66 100644 (file)
@@ -8,8 +8,8 @@ obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
 obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
 obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
 
-obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o
-obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o
+obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
+obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o
 
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
index 37a8a07beda3ea3a3a6bd0c5949eadf5f6830c29..9a34d393b813fe13633db30717f1684b2eaa8045 100644 (file)
@@ -64,6 +64,7 @@
 #define MXC_CCM_CCMR_SSI2S_MASK                 (0x3 << 21)
 #define MXC_CCM_CCMR_LPM_OFFSET                 14
 #define MXC_CCM_CCMR_LPM_MASK                   (0x3 << 14)
+#define MXC_CCM_CCMR_LPM_WAIT_MX35             (0x1 << 14)
 #define MXC_CCM_CCMR_FIRS_OFFSET                11
 #define MXC_CCM_CCMR_FIRS_MASK                  (0x3 << 11)
 #define MXC_CCM_CCMR_UPE                        (1 << 9)
index 31807d2a8b7bf1a65d57c8f4cb748bb9e6697934..905aafc1352c4692805c123cdf3e50d9b4dd11fd 100644 (file)
@@ -34,6 +34,8 @@ static void imx3_idle(void)
 {
        unsigned long reg = 0;
 
+       mx3_cpu_lp_set(MX3_WAIT);
+
        if (!need_resched())
                __asm__ __volatile__(
                        /* disable I and D cache */
diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c
new file mode 100644 (file)
index 0000000..b375243
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/io.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include "crmregs-imx3.h"
+
+/*
+ * Set cpu low power mode before WFI instruction. This function is called
+ * mx3 because it can be used for mx31 and mx35.
+ * Currently only WAIT_MODE is supported.
+ */
+void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode)
+{
+       int reg = __raw_readl(MXC_CCM_CCMR);
+       reg &= ~MXC_CCM_CCMR_LPM_MASK;
+
+       switch (mode) {
+       case MX3_WAIT:
+               if (cpu_is_mx35())
+                       reg |= MXC_CCM_CCMR_LPM_WAIT_MX35;
+               __raw_writel(reg, MXC_CCM_CCMR);
+               break;
+       default:
+               pr_err("Unknown cpu power mode: %d\n", mode);
+               return;
+       }
+}
index 1bf0df81bdc69dec5c08140454adcebc0f888dd0..06595a3d7ea352d8e50f72462be6279f676577b1 100644 (file)
@@ -84,6 +84,14 @@ enum mxc_cpu_pwr_mode {
        STOP_POWER_OFF,         /* STOP + SRPG */
 };
 
+enum mx3_cpu_pwr_mode {
+       MX3_RUN,
+       MX3_WAIT,
+       MX3_DOZE,
+       MX3_SLEEP,
+};
+
+extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
 extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
 extern void imx_print_silicon_rev(const char *cpu, int srev);