[PATCHv4 1/3] ARM: mx51: Add entry for gpc_dvfs_clk

Subsystems: arm port, the rest

8 messages, 4 authors, 2011-03-21 · open the first message on its own page

[PATCHv4 1/3] ARM: mx51: Add entry for gpc_dvfs_clk

From: <hidden>
Date: 2011-03-18 15:22:18

From: Dinh Nguyen <redacted>

For MX51 SRPG, we need to turn on the GPC clock in order to set the
SRPG registers.

Signed-off-by: Dinh Nguyen <redacted>
---
 arch/arm/mach-mx5/clock-mx51-mx53.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 652ace4..3eb1c6e 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -865,6 +865,13 @@ static struct clk aips_tz2_clk = {
 	.disable = _clk_ccgr_disable_inwait,
 };
 
+static struct clk gpc_dvfs_clk = {
+	.enable_reg = MXC_CCM_CCGR5,
+	.enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+	.enable = _clk_ccgr_enable,
+	.disable = _clk_ccgr_disable,
+};
+
 static struct clk gpt_32k_clk = {
 	.id = 0,
 	.parent = &ckil_clk,
@@ -1448,6 +1455,7 @@ static struct clk_lookup mx51_lookups[] = {
 	_REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
 	_REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
 	_REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
+	_REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk)
 };
 
 static struct clk_lookup mx53_lookups[] = {
-- 
1.6.0.4

[PATCHv4 3/3] ARM: mx51: Add support for low power suspend on MX51

From: <hidden>
Date: 2011-03-18 15:21:40

From: Dinh Nguyen <redacted>

Adds initial low power suspend functionality to MX51.
Supports "mem" and "standby" modes.

Tested on mx51-babbage.

Signed-off-by: Dinh Nguyen <redacted>
---
 arch/arm/mach-mx5/Makefile   |    1 +
 arch/arm/mach-mx5/pm-imx51.c |   74 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mx5/pm-imx51.c
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index 0b9338c..787cb80 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -6,6 +6,7 @@
 obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o
 obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
 
+obj-$(CONFIG_PM) += pm-imx51.o
 obj-$(CONFIG_CPU_FREQ_IMX)    += cpu_op-mx51.o
 obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
 obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
diff --git a/arch/arm/mach-mx5/pm-imx51.c b/arch/arm/mach-mx5/pm-imx51.c
new file mode 100644
index 0000000..49186e3
--- /dev/null
+++ b/arch/arm/mach-mx5/pm-imx51.c
@@ -0,0 +1,74 @@
+/*
+ *  Copyright (C) 2011 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/suspend.h>
+#include <linux/clk.h>
+#include <asm/mach/map.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+#include <mach/system.h>
+#include "crm_regs.h"
+
+static struct clk *gpc_dvfs_clk;
+
+static int mx5_suspend_enter(suspend_state_t state)
+{
+	if (gpc_dvfs_clk == NULL)
+		gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
+
+	if (gpc_dvfs_clk) {
+		clk_enable(gpc_dvfs_clk);
+		switch (state) {
+		case PM_SUSPEND_MEM:
+			mx5_cpu_lp_set(STOP_POWER_OFF);
+			break;
+		case PM_SUSPEND_STANDBY:
+			mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if (state == PM_SUSPEND_MEM) {
+			local_flush_tlb_all();
+			flush_cache_all();
+
+			/*clear the EMPGC0/1 bits */
+			__raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
+			__raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
+		}
+		cpu_do_idle();
+		clk_disable(gpc_dvfs_clk);
+	}else {
+		printk(KERN_ERR "Cannot enter SRPG suspend -no gpc_dvfs clock!\n");
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int mx5_pm_valid(suspend_state_t state)
+{
+	return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+static const struct platform_suspend_ops mx5_suspend_ops = {
+	.valid = mx5_pm_valid,
+	.enter = mx5_suspend_enter,
+};
+
+static int __init mx5_pm_init(void)
+{
+	if (cpu_is_mx51())
+		suspend_set_ops(&mx5_suspend_ops);
+
+	return 0;
+}
+device_initcall(mx5_pm_init);
-- 
1.6.0.4

[PATCHv4 2/3] ARM: mx51: Implement code to allow mx51 to enter WFI

From: <hidden>
Date: 2011-03-18 15:21:51

From: Dinh Nguyen <redacted>

Implement code for MX51 that allows the SoC to enter WFI when
arch_idle is called.

This patch is also necessary for correctly suspending the system.

Signed-off-by: Dinh Nguyen <redacted>
---
 arch/arm/mach-mx5/Makefile              |    2 +-
 arch/arm/mach-mx5/system.c              |   85 +++++++++++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/mxc.h    |    9 +++
 arch/arm/plat-mxc/include/mach/system.h |    6 ++-
 4 files changed, 100 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-mx5/system.c
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index 4f63048..0b9338c 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Object file lists.
-obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o
+obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o
 obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
 
 obj-$(CONFIG_CPU_FREQ_IMX)    += cpu_op-mx51.o
diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c
new file mode 100644
index 0000000..56c2bd1
--- /dev/null
+++ b/arch/arm/mach-mx5/system.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 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/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "crm_regs.h"
+
+/* set cpu low power mode before WFI instruction. This function is called
+  * mx5 because it can be used for mx50, mx51, and mx53.*/
+void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
+{
+	u32 plat_lpc, arm_srpgcr, ccm_clpcr;
+	u32 empgc0, empgc1;
+	int stop_mode = 0;
+
+	/* always allow platform to issue a deep sleep mode request */
+	plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) &
+	    ~(MXC_CORTEXA8_PLAT_LPC_DSM);
+	ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
+	arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
+	empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR);
+	empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR);
+
+	switch (mode) {
+	case WAIT_CLOCKED:
+		break;
+	case WAIT_UNCLOCKED:
+		ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+		break;
+	case WAIT_UNCLOCKED_POWER_OFF:
+	case STOP_POWER_OFF:
+		plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
+			    | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
+		if (mode == WAIT_UNCLOCKED_POWER_OFF) {
+			ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+			ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
+			ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
+			stop_mode = 0;
+		} else {
+			ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+			ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
+			ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+			ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
+			stop_mode = 1;
+		}
+		arm_srpgcr |= MXC_SRPGCR_PCR;
+
+		if (tzic_enable_wake(1) != 0)
+			return;
+		break;
+	case STOP_POWER_ON:
+		ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+		break;
+	default:
+		printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
+		return;
+	}
+
+	__raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
+	__raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+	__raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);
+
+	/* Enable NEON SRPG for all but MX50TO1.0. */
+	if (cpu_is_mx51() || cpu_is_mx53())
+		__raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
+
+	if (stop_mode) {
+		empgc0 |= MXC_SRPGCR_PCR;
+		empgc1 |= MXC_SRPGCR_PCR;
+
+		__raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
+		__raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
+	}
+}
+
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 7e07263..6c2a371 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -181,6 +181,15 @@ struct cpu_op {
 	u32 cpu_rate;
 };
 
+int tzic_enable_wake(int is_idle);
+enum mxc_cpu_pwr_mode {
+	WAIT_CLOCKED,		/* wfi only */
+	WAIT_UNCLOCKED,		/* WAIT */
+	WAIT_UNCLOCKED_POWER_OFF,	/* WAIT + SRPG */
+	STOP_POWER_ON,		/* just STOP */
+	STOP_POWER_OFF,		/* STOP + SRPG */
+};
+
 extern struct cpu_op *(*get_cpu_op)(int *op);
 #endif
 
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
index 95be51b..0417da9 100644
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ b/arch/arm/plat-mxc/include/mach/system.h
@@ -20,6 +20,8 @@
 #include <mach/hardware.h>
 #include <mach/common.h>
 
+extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
+
 static inline void arch_idle(void)
 {
 #ifdef CONFIG_ARCH_MXC91231
@@ -54,7 +56,9 @@ static inline void arch_idle(void)
 			"orr %0, %0, #0x00000004\n"
 			"mcr p15, 0, %0, c1, c0, 0\n"
 			: "=r" (reg));
-	} else
+	} else if (cpu_is_mx51())
+		mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+	else
 		cpu_do_idle();
 }
 
-- 
1.6.0.4

Re: [PATCHv4 3/3] ARM: mx51: Add support for low power suspend on MX51

From: Russell King - ARM Linux <hidden>
Date: 2011-03-18 15:25:16

On Fri, Mar 18, 2011 at 10:21:24AM -0500, Dinh.Nguyen at freescale.com wrote:
+#include <linux/suspend.h>
+#include <linux/clk.h>
+#include <asm/mach/map.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+#include <mach/system.h>
+#include "crm_regs.h"
Why does the code below require asm/mach/map.h ?
Why does it require asm/tlb.h ?
+
+static struct clk *gpc_dvfs_clk;
+
+static int mx5_suspend_enter(suspend_state_t state)
+{
+	if (gpc_dvfs_clk == NULL)
+		gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
+
+	if (gpc_dvfs_clk) {
+		clk_enable(gpc_dvfs_clk);
+		switch (state) {
+		case PM_SUSPEND_MEM:
+			mx5_cpu_lp_set(STOP_POWER_OFF);
+			break;
+		case PM_SUSPEND_STANDBY:
+			mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if (state == PM_SUSPEND_MEM) {
+			local_flush_tlb_all();
+			flush_cache_all();
+
+			/*clear the EMPGC0/1 bits */
+			__raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
+			__raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
+		}
+		cpu_do_idle();
+		clk_disable(gpc_dvfs_clk);
+	}else {
+		printk(KERN_ERR "Cannot enter SRPG suspend -no gpc_dvfs clock!\n");
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int mx5_pm_valid(suspend_state_t state)
+{
+	return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+static const struct platform_suspend_ops mx5_suspend_ops = {
+	.valid = mx5_pm_valid,
+	.enter = mx5_suspend_enter,
+};
+
+static int __init mx5_pm_init(void)
+{
+	if (cpu_is_mx51())
+		suspend_set_ops(&mx5_suspend_ops);
+
+	return 0;
+}
+device_initcall(mx5_pm_init);
-- 
1.6.0.4

Re: [PATCHv4 2/3] ARM: mx51: Implement code to allow mx51 to enter WFI

From: Fabio Estevam <festevam@gmail.com>
Date: 2011-03-18 15:31:13

Hi Dinh,

On Fri, Mar 18, 2011 at 12:21 PM,  [off-list ref] wrote:
...
+ ? ? ? /* Enable NEON SRPG for all but MX50TO1.0. */
+ ? ? ? if (cpu_is_mx51() || cpu_is_mx53())
+ ? ? ? ? ? ? ? __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
The comment says that NEON SRPG should not be enabled for MX50 TO1.0,
but your code does not check the MX50 silicon revision.

Regards,

Fabio Estevam

RE: [PATCHv4 2/3] ARM: mx51: Implement code to allow mx51 to enter WFI

From: Nguyen Dinh-R00091 <hidden>
Date: 2011-03-18 15:34:59

Hi Fabio,
-----Original Message-----
From: Fabio Estevam [mailto:festevam at gmail.com]
Sent: Friday, March 18, 2011 10:31 AM
To: Nguyen Dinh-R00091
Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
linux at arm.linux.org.uk; s.hauer at pengutronix.de; u.kleine-
koenig at pengutronix.de; arnaud.patard at rtp-net.org; Vaidyanathan Ranjani-
RA5478; Zhang Lily-R58066
Subject: Re: [PATCHv4 2/3] ARM: mx51: Implement code to allow mx51 to
enter WFI

Hi Dinh,

On Fri, Mar 18, 2011 at 12:21 PM,  [off-list ref] wrote:
...
quoted
+ ? ? ? /* Enable NEON SRPG for all but MX50TO1.0. */
+ ? ? ? if (cpu_is_mx51() || cpu_is_mx53())
+ ? ? ? ? ? ? ? __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
The comment says that NEON SRPG should not be enabled for MX50 TO1.0,
but your code does not check the MX50 silicon revision.
There is no mechanism for checking MX50 Revisions yet. I'll work on adding the MX50 revision check.

Dinh
Regards,

Fabio Estevam

RE: [PATCHv4 3/3] ARM: mx51: Add support for low power suspend on MX51

From: Nguyen Dinh-R00091 <hidden>
Date: 2011-03-21 14:55:32

Hi Russell,
-----Original Message-----
From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-owner at vger.kernel.org] On Behalf Of
Russell King - ARM Linux
Sent: Friday, March 18, 2011 10:25 AM
To: Nguyen Dinh-R00091
Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; s.hauer at pengutronix.de;
u.kleine-koenig at pengutronix.de; arnaud.patard at rtp-net.org; Vaidyanathan Ranjani-RA5478; Zhang Lily-
R58066; festevam at gmail.com
Subject: Re: [PATCHv4 3/3] ARM: mx51: Add support for low power suspend on MX51

On Fri, Mar 18, 2011 at 10:21:24AM -0500, Dinh.Nguyen at freescale.com wrote:
quoted
+#include <linux/suspend.h>
+#include <linux/clk.h>
+#include <asm/mach/map.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+#include <mach/system.h>
+#include "crm_regs.h"
Why does the code below require asm/mach/map.h ?
map.h can be replaced by linux/io.h for the __raw_writel().
Why does it require asm/tlb.h ?
asm/tlb is for the local_flush_tlb_all() call.

Thanks for your review.

Dinh
quoted
+
+static struct clk *gpc_dvfs_clk;
+
+static int mx5_suspend_enter(suspend_state_t state)
+{
+	if (gpc_dvfs_clk == NULL)
+		gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
+
+	if (gpc_dvfs_clk) {
+		clk_enable(gpc_dvfs_clk);
+		switch (state) {
+		case PM_SUSPEND_MEM:
+			mx5_cpu_lp_set(STOP_POWER_OFF);
+			break;
+		case PM_SUSPEND_STANDBY:
+			mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if (state == PM_SUSPEND_MEM) {
+			local_flush_tlb_all();
+			flush_cache_all();
+
+			/*clear the EMPGC0/1 bits */
+			__raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
+			__raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
+		}
+		cpu_do_idle();
+		clk_disable(gpc_dvfs_clk);
+	}else {
+		printk(KERN_ERR "Cannot enter SRPG suspend -no gpc_dvfs clock!\n");
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int mx5_pm_valid(suspend_state_t state)
+{
+	return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+static const struct platform_suspend_ops mx5_suspend_ops = {
+	.valid = mx5_pm_valid,
+	.enter = mx5_suspend_enter,
+};
+
+static int __init mx5_pm_init(void)
+{
+	if (cpu_is_mx51())
+		suspend_set_ops(&mx5_suspend_ops);
+
+	return 0;
+}
+device_initcall(mx5_pm_init);
--
1.6.0.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at 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: [PATCHv4 3/3] ARM: mx51: Add support for low power suspend on MX51

From: Russell King - ARM Linux <hidden>
Date: 2011-03-21 15:48:48

On Mon, Mar 21, 2011 at 02:53:21PM +0000, Nguyen Dinh-R00091 wrote:
quoted
On Fri, Mar 18, 2011 at 10:21:24AM -0500, Dinh.Nguyen at freescale.com wrote:
quoted
+#include <linux/suspend.h>
+#include <linux/clk.h>
+#include <asm/mach/map.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+#include <mach/system.h>
+#include "crm_regs.h"
Why does the code below require asm/mach/map.h ?
map.h can be replaced by linux/io.h for the __raw_writel().
quoted
Why does it require asm/tlb.h ?
asm/tlb is for the local_flush_tlb_all() call.
I think you want asm/tlbflush.h rather than the tlb shootdown stuff in
asm/tlb.h.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help