Skip to contentSkip to conversation

cpuidle driver on iMX platform

PATCH Superseded yong.shen at linaro.org 5 participants 12 messages Feb 8, 2011 – Feb 9, 2011

Subsystems (3)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

cover cpuidle driver on iMX platform

Also to freescale list, since there is no such driver in freescale bsp so far.

Yong

#1 lore raw

PATCH 1/2 ARM: iMX: cpuidle driver

From: Yong Shen <[email protected]>

implement cpu idle driver which allow different imx SOCs and boards to register their own cpuidle parameters

---
 arch/arm/plat-mxc/Makefile               |    1 +
 arch/arm/plat-mxc/cpuidle.c              |   74 ++++++++++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/cpuidle.h |    6 ++
 3 files changed, 81 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-mxc/cpuidle.c
 create mode 100644 arch/arm/plat-mxc/include/mach/cpuidle.h
arch/arm/plat-mxc/Makefile +1 -0
index 5fd20e9..e6ba9c2 100644
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
 obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
 obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
 obj-$(CONFIG_CPU_FREQ_IMX)    += cpufreq.o
+obj-$(CONFIG_CPU_IDLE)    += cpuidle.o
 ifdef CONFIG_SND_IMX_SOC
 obj-y += ssi-fiq.o
 obj-y += ssi-fiq-ksym.o
arch/arm/plat-mxc/cpuidle.c new file +74 -0

74 lines not on this page · raw message

arch/arm/plat-mxc/include/mach/cpuidle.h new file +6 -0
new file mode 100644
index 0000000..4d672aa
@@ -0,0 +1,6 @@
+#include <linux/cpuidle.h>
+
+struct imx_cpuidle_state {
+	unsigned short state_number;
+	struct cpuidle_state *state;
+};
Signature · 1 line
1.7.1
#2 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

In reply to yong.shen at linaro.org

From: Yong Shen <[email protected]>

Add cpuidle parameters to make cpuidle driver workable, but these parameters need further tuning

---
 arch/arm/mach-mx5/board-mx51_babbage.c |  114 ++++++++++++++++++++++++++++++++
 arch/arm/mach-mx5/devices.c            |    4 +
 arch/arm/mach-mx5/devices.h            |    1 +
 3 files changed, 119 insertions(+), 0 deletions(-)
arch/arm/mach-mx5/board-mx51_babbage.c +114 -0
index d9d402e..3c661e9 100644
@@ -22,11 +22,13 @@
 #include <linux/input.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
+#include <linux/cpuidle.h>
 
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-mx51.h>
 #include <mach/mxc_ehci.h>
+#include <mach/cpuidle.h>
 
 #include <asm/irq.h>
 #include <asm/setup.h>
@@ -37,6 +39,7 @@
 #include "devices-imx51.h"
 #include "devices.h"
 #include "cpu_op-mx51.h"
+#include "crm_regs.h"
 
 #define BABBAGE_USB_HUB_RESET	IMX_GPIO_NR(1, 7)
 #define BABBAGE_USBH1_STP	IMX_GPIO_NR(1, 27)
@@ -333,6 +336,117 @@ static const struct spi_imx_master mx51_babbage_spi_pdata __initconst = {
 	.num_chipselect = ARRAY_SIZE(mx51_babbage_spi_cs),
 };
 
+extern int tzic_enable_wake(int is_idle);
+static int imx51_enter_idle(struct cpuidle_device *dev,
+			       struct cpuidle_state *state)
+{
+	struct timeval before, after;
+	int idle_time;
+	u32 plat_lpc, arm_srpgcr, ccm_clpcr;
+	u32 empgc0, empgc1;
+	int stop_mode = 0;
+
+	local_irq_disable();
+	do_gettimeofday(&before);
+
+	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);
+
+	if (state == &dev->states[0]) {
+		/* Wait clocked */
+		;
+	} else if (state == &dev->states[1]) {
+		/* Wait unclocked */
+		ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET);
+	} else {
+		plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
+			    | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
+		arm_srpgcr |= MXC_SRPGCR_PCR;
+		if (state == &dev->states[2]) {
+			/* 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 if (state == &dev->states[3]) {
+			/* Stop power off */
+			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;
+			empgc0 |= MXC_SRPGCR_PCR;
+			empgc1 |= MXC_SRPGCR_PCR;
+			stop_mode = 1;
+		}
+		if (tzic_enable_wake(1) != 0) {
+			local_irq_enable();
+			return 0;
+		}
+	}
+
+	__raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
+	__raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+	__raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);
+
+	if (stop_mode) {
+		__raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
+		__raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
+	}
+
+	cpu_do_idle();
+
+	do_gettimeofday(&after);
+	local_irq_enable();
+	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+			(after.tv_usec - before.tv_usec);
+	return idle_time;
+}
+
+static struct cpuidle_state babbage_cpuidle_state[] = {
+	{
+		.enter			= imx51_enter_idle,
+		.exit_latency		= 1,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "WFI",
+		.desc			= "Wait with clock on",
+	},
+	{
+		.enter			= imx51_enter_idle,
+		.exit_latency		= 100,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "WFI",
+		.desc			= "Wait with clock off",
+	},
+	{
+		.enter			= imx51_enter_idle,
+		.exit_latency		= 10000,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "WFI",
+		.desc			= "Wait with clock off/power gating",
+	},
+	{
+		.enter			= imx51_enter_idle,
+		.exit_latency		= 1000000,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "SR",
+		.desc			= "state retention",
+	},
+};
+
+static struct imx_cpuidle_state babbage_cpuidle_data = {
+	.state_number = ARRAY_SIZE(babbage_cpuidle_state),
+	.state = babbage_cpuidle_state,
+};
+
+static int imx51_init_cpuidle(void)
+{
+	return mxc_register_device(&mxc_cpuidle_device, &babbage_cpuidle_data);
+}
+device_initcall(imx51_init_cpuidle);
 /*
  * Board specific initialization.
  */
arch/arm/mach-mx5/devices.c +4 -0
index 153ada5..8daf5f6 100644
@@ -37,6 +37,10 @@ struct platform_device mxc_hsi2c_device = {
 	.resource = mxc_hsi2c_resources
 };
 
+struct platform_device mxc_cpuidle_device = {
+	.name = "imx_cpuidle",
+};
+
 static u64 usb_dma_mask = DMA_BIT_MASK(32);
 
 static struct resource usbotg_resources[] = {
arch/arm/mach-mx5/devices.h +1 -0
index 55a5129..49e441c 100644
@@ -3,3 +3,4 @@ extern struct platform_device mxc_usbh1_device;
 extern struct platform_device mxc_usbh2_device;
 extern struct platform_device mxc_usbdr_udc_device;
 extern struct platform_device mxc_hsi2c_device;
+extern struct platform_device mxc_cpuidle_device;
Signature · 1 line
1.7.1
#3 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

yong.shen at linaro.org writes:

Hi,

Quoted 11 lines

From: Yong Shen <[email protected]>

Add cpuidle parameters to make cpuidle driver workable, but these parameters need further tuning

---
 arch/arm/mach-mx5/board-mx51_babbage.c |  114 ++++++++++++++++++++++++++++++++
 arch/arm/mach-mx5/devices.c            |    4 +
 arch/arm/mach-mx5/devices.h            |    1 +
 3 files changed, 119 insertions(+), 0 deletions(-)

I didn't look at how it's working nor did a review but from a very quick look, I'm wondering why it's in board-mx51_babbage.c. Can you explain to me what makes this code specific to babbage ?

Arnaud

author
#4 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

Hi Arnaud,

I also took a while to think about this before posting patches. I prefer to put it in board related code since the various PMIC used on each boards may have influence on cpuidle latency or other charactors, although it could be minor.

Yong

Quoted 17 lines · Arnaud Patard

yong.shen at linaro.org writes:

Hi,

Quoted 8 lines

From: Yong Shen <[email protected]>

Add cpuidle parameters to make cpuidle driver workable, but these parameters need further tuning

---
 arch/arm/mach-mx5/board-mx51_babbage.c |  114

++++++++++++++++++++++++++++++++

Quoted 3 lines
 arch/arm/mach-mx5/devices.c            |    4 +
 arch/arm/mach-mx5/devices.h            |    1 +
 3 files changed, 119 insertions(+), 0 deletions(-)
Quoted 6 lines

I didn't look at how it's working nor did a review but from a very quick look, I'm wondering why it's in board-mx51_babbage.c. Can you explain to me what makes this code specific to babbage ?

Arnaud

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110208/a7913e49/attachment-0001.html>

#5 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

Quoted 7 lines · Yong Shen

Hi Arnaud,

I also took a while to think about this before posting patches. I prefer to put it in board related code since the various PMIC used on each boards may have influence on cpuidle latency or other charactors, although it could be minor.

Then those minor differences can be addressed in the common driver by using #ifdef conditionals.

The cpuidle driver certainly shouldn't be board-specific.

/Amit

#6 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

Quoted 9 lines · Amit Kucheria
Quoted 7 lines · Yong Shen

Hi Arnaud,

I also took a while to think about this before posting patches. I prefer to put it in board related code since the various PMIC used on each boards may have influence on cpuidle latency or other charactors, although it could be minor.

Quoted 4 lines

Then those minor differences can be addressed in the common driver by using #ifdef conditionals.

The cpuidle driver certainly shouldn't be board-specific.

agreed, except on #ifdef. One should be able to build one kernel for several imx51 boards and #ifdef will probably prevent that.

Arnaud

#7 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

Quoted 11 lines · Arnaud Patard
Quoted 9 lines · Amit Kucheria
Quoted 7 lines · Yong Shen

Hi Arnaud,

I also took a while to think about this before posting patches. I prefer to put it in board related code since the various PMIC used on each boards may have influence on cpuidle latency or other charactors, although it could be minor.

Quoted 7 lines
Quoted 4 lines

Then those minor differences can be addressed in the common driver by using #ifdef conditionals.

The cpuidle driver certainly shouldn't be board-specific.

agreed, except on #ifdef. One should be able to build one kernel for several imx51 boards and #ifdef will probably prevent that.

You're right. I should've said runtime detection.

#8 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

In reply to Yong Shen
Quoted 7 lines · Yong Shen

Hi Arnaud,

I also took a while to think about this before posting patches. I prefer to put it in board related code since the various PMIC used on each boards may have influence on cpuidle latency or other charactors, although it could be minor.

But you are not going to be doing voltage scaling in idle. Is it even possible to do sleeping operations like accessing a PMIC in idle?

The core is powergated, so lowering voltage would not help. Doing bus scaling or DDR self-refresh are the only likely additional operations.

Rob

author
#9 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

Quoted 4 lines · Rob Herring
Quoted 2 lines · Yong Shen

Hi Arnaud,

Quoted 9 lines
Quoted 6 lines

I also took a while to think about this before posting patches. I prefer to put it in board related code since the various PMIC used on each boards may have influence on cpuidle latency or other charactors, although it could be minor.

But you are not going to be doing voltage scaling in idle. Is it even possible to do sleeping operations like accessing a PMIC in idle?

I guess you are asking if modes like 'state retention' are possible for idle state. so far there is no official mapping between c-states and various arm idle states, which is something linaro power management group is working on. Therefore I also treat 'state retention' as a c-state.

ps. remove lpdk in cc list to avoid auto-reply messages. Yong

Quoted 6 lines

The core is powergated, so lowering voltage would not help. Doing bus scaling or DDR self-refresh are the only likely additional operations.

Rob

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110209/fe299280/attachment-0001.html>

#10 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

In reply to Yong Shen

Yong,

Quoted 5 lines · Yong Shen

Hi Arnaud,
I also took a while to think about this before posting patches. I prefer to put it in board related code since the various PMIC used on each boards may have influence on cpuidle latency or other charactors, although it could be minor.

WHy don't you define cpuidle_latency table per board file and use the right one inside the common cpuidle driver. Then you can take care of board related latencies cleanly.

Vishwa

Quoted 35 lines

Yong

Quoted 18 lines · Arnaud Patard

yong.shen at linaro.org writes:

Hi,

Quoted 5 lines

From: Yong Shen <[email protected]>

Add cpuidle parameters to make cpuidle driver workable, but these parameters need further tuning

Quoted 7 lines

---
?arch/arm/mach-mx5/board-mx51_babbage.c | ?114
++++++++++++++++++++++++++++++++
?arch/arm/mach-mx5/devices.c ? ? ? ? ? ?| ? ?4 + ?arch/arm/mach-mx5/devices.h ? ? ? ? ? ?| ? ?1 + ?3 files changed, 119 insertions(+), 0 deletions(-)

Quoted 5 lines

I didn't look at how it's working nor did a review but from a very quick look, I'm wondering why it's in board-mx51_babbage.c. Can you explain to me what makes this code specific to babbage ?

Arnaud

_______________________________________________
linaro-dev mailing list
linaro-dev at lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

author
#11 lore raw

PATCH 2/2 ARM: iMX5 BBG: add cpuidle driver parameters

Hi Vishwanath,

Thanks. I will take it as a reference.

Yong

Quoted 8 lines · Vishwanath Sripathy

Yong,

Quoted 2 lines · Yong Shen

Hi Arnaud,
I also took a while to think about this before posting patches. I prefer

to

Quoted 1 line

put it in board related code since the various PMIC used on each boards

may

Quoted 45 lines
Quoted 1 line

have influence on cpuidle latency or other charactors, although it could

be

Quoted 1 line

minor.

WHy don't you define cpuidle_latency table per board file and use the right one inside the common cpuidle driver. Then you can take care of board related latencies cleanly.

Vishwa

Quoted 36 lines

Yong

On Tue, Feb 8, 2011 at 4:29 PM, Arnaud Patard <[email protected]

Quoted 18 lines · wrote:

yong.shen at linaro.org writes:

Hi,

Quoted 5 lines

From: Yong Shen <[email protected]>

Add cpuidle parameters to make cpuidle driver workable, but these parameters need further tuning

Quoted 7 lines
---
 arch/arm/mach-mx5/board-mx51_babbage.c |  114
++++++++++++++++++++++++++++++++
 arch/arm/mach-mx5/devices.c            |    4 +
 arch/arm/mach-mx5/devices.h            |    1 +
 3 files changed, 119 insertions(+), 0 deletions(-)
Quoted 5 lines

I didn't look at how it's working nor did a review but from a very quick look, I'm wondering why it's in board-mx51_babbage.c. Can you explain to me what makes this code specific to babbage ?

Arnaud

_______________________________________________
linaro-dev mailing list
linaro-dev at lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110209/1a78d9d0/attachment-0001.html>