aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/cpuidle44xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/cpuidle44xx.c')
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c126
1 files changed, 52 insertions, 74 deletions
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index f386cbe9c889..be1617ca84bd 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -24,26 +24,31 @@
24 24
25#ifdef CONFIG_CPU_IDLE 25#ifdef CONFIG_CPU_IDLE
26 26
27/* Machine specific information to be recorded in the C-state driver_data */ 27/* Machine specific information */
28struct omap4_idle_statedata { 28struct omap4_idle_statedata {
29 u32 cpu_state; 29 u32 cpu_state;
30 u32 mpu_logic_state; 30 u32 mpu_logic_state;
31 u32 mpu_state; 31 u32 mpu_state;
32 u8 valid;
33}; 32};
34 33
35static struct cpuidle_params cpuidle_params_table[] = { 34static struct omap4_idle_statedata omap4_idle_data[] = {
36 /* C1 - CPU0 ON + CPU1 ON + MPU ON */ 35 {
37 {.exit_latency = 2 + 2 , .target_residency = 5, .valid = 1}, 36 .cpu_state = PWRDM_POWER_ON,
38 /* C2- CPU0 OFF + CPU1 OFF + MPU CSWR */ 37 .mpu_state = PWRDM_POWER_ON,
39 {.exit_latency = 328 + 440 , .target_residency = 960, .valid = 1}, 38 .mpu_logic_state = PWRDM_POWER_RET,
40 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ 39 },
41 {.exit_latency = 460 + 518 , .target_residency = 1100, .valid = 1}, 40 {
41 .cpu_state = PWRDM_POWER_OFF,
42 .mpu_state = PWRDM_POWER_RET,
43 .mpu_logic_state = PWRDM_POWER_RET,
44 },
45 {
46 .cpu_state = PWRDM_POWER_OFF,
47 .mpu_state = PWRDM_POWER_RET,
48 .mpu_logic_state = PWRDM_POWER_OFF,
49 },
42}; 50};
43 51
44#define OMAP4_NUM_STATES ARRAY_SIZE(cpuidle_params_table)
45
46struct omap4_idle_statedata omap4_idle_data[OMAP4_NUM_STATES];
47static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; 52static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd;
48 53
49/** 54/**
@@ -60,8 +65,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
60 struct cpuidle_driver *drv, 65 struct cpuidle_driver *drv,
61 int index) 66 int index)
62{ 67{
63 struct omap4_idle_statedata *cx = 68 struct omap4_idle_statedata *cx = &omap4_idle_data[index];
64 cpuidle_get_statedata(&dev->states_usage[index]);
65 u32 cpu1_state; 69 u32 cpu1_state;
66 int cpu_id = smp_processor_id(); 70 int cpu_id = smp_processor_id();
67 71
@@ -78,7 +82,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
78 cpu1_state = pwrdm_read_pwrst(cpu1_pd); 82 cpu1_state = pwrdm_read_pwrst(cpu1_pd);
79 if (cpu1_state != PWRDM_POWER_OFF) { 83 if (cpu1_state != PWRDM_POWER_OFF) {
80 index = drv->safe_state_index; 84 index = drv->safe_state_index;
81 cx = cpuidle_get_statedata(&dev->states_usage[index]); 85 cx = &omap4_idle_data[index];
82 } 86 }
83 87
84 if (index > 0) 88 if (index > 0)
@@ -133,36 +137,39 @@ struct cpuidle_driver omap4_idle_driver = {
133 .name = "omap4_idle", 137 .name = "omap4_idle",
134 .owner = THIS_MODULE, 138 .owner = THIS_MODULE,
135 .en_core_tk_irqen = 1, 139 .en_core_tk_irqen = 1,
140 .states = {
141 {
142 /* C1 - CPU0 ON + CPU1 ON + MPU ON */
143 .exit_latency = 2 + 2,
144 .target_residency = 5,
145 .flags = CPUIDLE_FLAG_TIME_VALID,
146 .enter = omap4_enter_idle,
147 .name = "C1",
148 .desc = "MPUSS ON"
149 },
150 {
151 /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
152 .exit_latency = 328 + 440,
153 .target_residency = 960,
154 .flags = CPUIDLE_FLAG_TIME_VALID,
155 .enter = omap4_enter_idle,
156 .name = "C2",
157 .desc = "MPUSS CSWR",
158 },
159 {
160 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
161 .exit_latency = 460 + 518,
162 .target_residency = 1100,
163 .flags = CPUIDLE_FLAG_TIME_VALID,
164 .enter = omap4_enter_idle,
165 .name = "C3",
166 .desc = "MPUSS OSWR",
167 },
168 },
169 .state_count = ARRAY_SIZE(omap4_idle_data),
170 .safe_state_index = 0,
136}; 171};
137 172
138static inline void _fill_cstate(struct cpuidle_driver *drv,
139 int idx, const char *descr)
140{
141 struct cpuidle_state *state = &drv->states[idx];
142
143 state->exit_latency = cpuidle_params_table[idx].exit_latency;
144 state->target_residency = cpuidle_params_table[idx].target_residency;
145 state->flags = CPUIDLE_FLAG_TIME_VALID;
146 state->enter = omap4_enter_idle;
147 sprintf(state->name, "C%d", idx + 1);
148 strncpy(state->desc, descr, CPUIDLE_DESC_LEN);
149}
150
151static inline struct omap4_idle_statedata *_fill_cstate_usage(
152 struct cpuidle_device *dev,
153 int idx)
154{
155 struct omap4_idle_statedata *cx = &omap4_idle_data[idx];
156 struct cpuidle_state_usage *state_usage = &dev->states_usage[idx];
157
158 cx->valid = cpuidle_params_table[idx].valid;
159 cpuidle_set_statedata(state_usage, cx);
160
161 return cx;
162}
163
164
165
166/** 173/**
167 * omap4_idle_init - Init routine for OMAP4 idle 174 * omap4_idle_init - Init routine for OMAP4 idle
168 * 175 *
@@ -171,9 +178,7 @@ static inline struct omap4_idle_statedata *_fill_cstate_usage(
171 */ 178 */
172int __init omap4_idle_init(void) 179int __init omap4_idle_init(void)
173{ 180{
174 struct omap4_idle_statedata *cx;
175 struct cpuidle_device *dev; 181 struct cpuidle_device *dev;
176 struct cpuidle_driver *drv = &omap4_idle_driver;
177 unsigned int cpu_id = 0; 182 unsigned int cpu_id = 0;
178 183
179 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 184 mpu_pd = pwrdm_lookup("mpu_pwrdm");
@@ -182,42 +187,15 @@ int __init omap4_idle_init(void)
182 if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) 187 if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd))
183 return -ENODEV; 188 return -ENODEV;
184 189
185
186 drv->safe_state_index = -1;
187 dev = &per_cpu(omap4_idle_dev, cpu_id); 190 dev = &per_cpu(omap4_idle_dev, cpu_id);
188 dev->cpu = cpu_id; 191 dev->cpu = cpu_id;
189 192
190 /* C1 - CPU0 ON + CPU1 ON + MPU ON */
191 _fill_cstate(drv, 0, "MPUSS ON");
192 drv->safe_state_index = 0;
193 cx = _fill_cstate_usage(dev, 0);
194 cx->valid = 1; /* C1 is always valid */
195 cx->cpu_state = PWRDM_POWER_ON;
196 cx->mpu_state = PWRDM_POWER_ON;
197 cx->mpu_logic_state = PWRDM_POWER_RET;
198
199 /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
200 _fill_cstate(drv, 1, "MPUSS CSWR");
201 cx = _fill_cstate_usage(dev, 1);
202 cx->cpu_state = PWRDM_POWER_OFF;
203 cx->mpu_state = PWRDM_POWER_RET;
204 cx->mpu_logic_state = PWRDM_POWER_RET;
205
206 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
207 _fill_cstate(drv, 2, "MPUSS OSWR");
208 cx = _fill_cstate_usage(dev, 2);
209 cx->cpu_state = PWRDM_POWER_OFF;
210 cx->mpu_state = PWRDM_POWER_RET;
211 cx->mpu_logic_state = PWRDM_POWER_OFF;
212
213 drv->state_count = OMAP4_NUM_STATES;
214 cpuidle_register_driver(&omap4_idle_driver); 193 cpuidle_register_driver(&omap4_idle_driver);
215 194
216 dev->state_count = OMAP4_NUM_STATES;
217 if (cpuidle_register_device(dev)) { 195 if (cpuidle_register_device(dev)) {
218 pr_err("%s: CPUidle register device failed\n", __func__); 196 pr_err("%s: CPUidle register device failed\n", __func__);
219 return -EIO; 197 return -EIO;
220 } 198 }
221 199
222 return 0; 200 return 0;
223} 201}