-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ARM: imx: support arm power off in cpuidle for i.mx6sx
This patch introduces an independent cpuidle driver for i.MX6SX, and supports arm power off in idle, totally 3 levels of cpuidle are supported as below: 1. ARM WFI; 2. SOC in WAIT mode; 3. SOC in WAIT mode + ARM power off. ARM power off can save at least 5mW power. This patch also replaces imx6q_enable_rbc with imx6_enable_rbc. Signed-off-by: Anson Huang <b20788@freescale.com> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
- Loading branch information
Anson Huang
authored and
Shawn Guo
committed
Jan 5, 2015
1 parent
df096fd
commit 05136f0
Showing
7 changed files
with
144 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* Copyright (C) 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. | ||
*/ | ||
|
||
#include <linux/cpuidle.h> | ||
#include <linux/cpu_pm.h> | ||
#include <linux/module.h> | ||
#include <asm/cpuidle.h> | ||
#include <asm/proc-fns.h> | ||
#include <asm/suspend.h> | ||
|
||
#include "common.h" | ||
#include "cpuidle.h" | ||
|
||
static int imx6sx_idle_finish(unsigned long val) | ||
{ | ||
cpu_do_idle(); | ||
|
||
return 0; | ||
} | ||
|
||
static int imx6sx_enter_wait(struct cpuidle_device *dev, | ||
struct cpuidle_driver *drv, int index) | ||
{ | ||
imx6q_set_lpm(WAIT_UNCLOCKED); | ||
|
||
switch (index) { | ||
case 1: | ||
cpu_do_idle(); | ||
break; | ||
case 2: | ||
imx6_enable_rbc(true); | ||
imx_gpc_set_arm_power_in_lpm(true); | ||
imx_set_cpu_jump(0, v7_cpu_resume); | ||
/* Need to notify there is a cpu pm operation. */ | ||
cpu_pm_enter(); | ||
cpu_cluster_pm_enter(); | ||
|
||
cpu_suspend(0, imx6sx_idle_finish); | ||
|
||
cpu_cluster_pm_exit(); | ||
cpu_pm_exit(); | ||
imx_gpc_set_arm_power_in_lpm(false); | ||
imx6_enable_rbc(false); | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
imx6q_set_lpm(WAIT_CLOCKED); | ||
|
||
return index; | ||
} | ||
|
||
static struct cpuidle_driver imx6sx_cpuidle_driver = { | ||
.name = "imx6sx_cpuidle", | ||
.owner = THIS_MODULE, | ||
.states = { | ||
/* WFI */ | ||
ARM_CPUIDLE_WFI_STATE, | ||
/* WAIT */ | ||
{ | ||
.exit_latency = 50, | ||
.target_residency = 75, | ||
.flags = CPUIDLE_FLAG_TIME_VALID | | ||
CPUIDLE_FLAG_TIMER_STOP, | ||
.enter = imx6sx_enter_wait, | ||
.name = "WAIT", | ||
.desc = "Clock off", | ||
}, | ||
/* WAIT + ARM power off */ | ||
{ | ||
/* | ||
* ARM gating 31us * 5 + RBC clear 65us | ||
* and some margin for SW execution, here set it | ||
* to 300us. | ||
*/ | ||
.exit_latency = 300, | ||
.target_residency = 500, | ||
.flags = CPUIDLE_FLAG_TIME_VALID, | ||
.enter = imx6sx_enter_wait, | ||
.name = "LOW-POWER-IDLE", | ||
.desc = "ARM power off", | ||
}, | ||
}, | ||
.state_count = 3, | ||
.safe_state_index = 0, | ||
}; | ||
|
||
int __init imx6sx_cpuidle_init(void) | ||
{ | ||
imx6_enable_rbc(false); | ||
/* | ||
* set ARM power up/down timing to the fastest, | ||
* sw2iso and sw can be set to one 32K cycle = 31us | ||
* except for power up sw2iso which need to be | ||
* larger than LDO ramp up time. | ||
*/ | ||
imx_gpc_set_arm_power_up_timing(2, 1); | ||
imx_gpc_set_arm_power_down_timing(1, 1); | ||
|
||
return cpuidle_register(&imx6sx_cpuidle_driver, NULL); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters