aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-02-23 22:22:48 -0500
committerTony Lindgren <tony@atomide.com>2010-02-23 22:22:48 -0500
commit0fdc54b2019700a4b50179914e810367c14044a3 (patch)
tree73e5e34f30aec87ad4bf4423c4f95ebba576359e
parent8250a5c381cc6714a061a39cfd29d7453e8ad64b (diff)
parent79dcfdd407208cba06bd446e93b0809df1cf10d1 (diff)
Merge branch 'pm-2.6.34' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c20
-rw-r--r--arch/arm/mach-omap2/board-rx51.c44
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c226
-rw-r--r--arch/arm/mach-omap2/pm.h20
-rw-r--r--arch/arm/mach-omap2/pm34xx.c4
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S59
-rw-r--r--arch/arm/plat-omap/Kconfig17
7 files changed, 352 insertions, 38 deletions
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index a10e96f48aea..f312b1513753 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -46,6 +46,7 @@
46#include "mux.h" 46#include "mux.h"
47#include "sdram-qimonda-hyb18m512160af-6.h" 47#include "sdram-qimonda-hyb18m512160af-6.h"
48#include "hsmmc.h" 48#include "hsmmc.h"
49#include "pm.h"
49 50
50#define CONFIG_DISABLE_HFCLK 1 51#define CONFIG_DISABLE_HFCLK 1
51 52
@@ -57,6 +58,24 @@
57 58
58#define TWL4030_MSECURE_GPIO 22 59#define TWL4030_MSECURE_GPIO 22
59 60
61/* FIXME: These values need to be updated based on more profiling on 3430sdp*/
62static struct cpuidle_params omap3_cpuidle_params_table[] = {
63 /* C1 */
64 {1, 2, 2, 5},
65 /* C2 */
66 {1, 10, 10, 30},
67 /* C3 */
68 {1, 50, 50, 300},
69 /* C4 */
70 {1, 1500, 1800, 4000},
71 /* C5 */
72 {1, 2500, 7500, 12000},
73 /* C6 */
74 {1, 3000, 8500, 15000},
75 /* C7 */
76 {1, 10000, 30000, 300000},
77};
78
60static int board_keymap[] = { 79static int board_keymap[] = {
61 KEY(0, 0, KEY_LEFT), 80 KEY(0, 0, KEY_LEFT),
62 KEY(0, 1, KEY_RIGHT), 81 KEY(0, 1, KEY_RIGHT),
@@ -307,6 +326,7 @@ static void __init omap_3430sdp_init_irq(void)
307{ 326{
308 omap_board_config = sdp3430_config; 327 omap_board_config = sdp3430_config;
309 omap_board_config_size = ARRAY_SIZE(sdp3430_config); 328 omap_board_config_size = ARRAY_SIZE(sdp3430_config);
329 omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
310 omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL); 330 omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
311 omap_init_irq(); 331 omap_init_irq();
312 omap_gpio_init(); 332 omap_gpio_init();
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 0ccb8b46d157..b155c366c650 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -16,6 +16,7 @@
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/gpio.h> 18#include <linux/gpio.h>
19#include <linux/leds.h>
19 20
20#include <mach/hardware.h> 21#include <mach/hardware.h>
21#include <asm/mach-types.h> 22#include <asm/mach-types.h>
@@ -30,9 +31,49 @@
30#include <plat/usb.h> 31#include <plat/usb.h>
31 32
32#include "mux.h" 33#include "mux.h"
34#include "pm.h"
35
36#define RX51_GPIO_SLEEP_IND 162
33 37
34struct omap_sdrc_params *rx51_get_sdram_timings(void); 38struct omap_sdrc_params *rx51_get_sdram_timings(void);
35 39
40static struct gpio_led gpio_leds[] = {
41 {
42 .name = "sleep_ind",
43 .gpio = RX51_GPIO_SLEEP_IND,
44 },
45};
46
47static struct gpio_led_platform_data gpio_led_info = {
48 .leds = gpio_leds,
49 .num_leds = ARRAY_SIZE(gpio_leds),
50};
51
52static struct platform_device leds_gpio = {
53 .name = "leds-gpio",
54 .id = -1,
55 .dev = {
56 .platform_data = &gpio_led_info,
57 },
58};
59
60static struct cpuidle_params rx51_cpuidle_params[] = {
61 /* C1 */
62 {1, 110, 162, 5},
63 /* C2 */
64 {1, 106, 180, 309},
65 /* C3 */
66 {0, 107, 410, 46057},
67 /* C4 */
68 {0, 121, 3374, 46057},
69 /* C5 */
70 {1, 855, 1146, 46057},
71 /* C6 */
72 {0, 7580, 4134, 484329},
73 /* C7 */
74 {1, 7505, 15274, 484329},
75};
76
36static struct omap_lcd_config rx51_lcd_config = { 77static struct omap_lcd_config rx51_lcd_config = {
37 .ctrl_name = "internal", 78 .ctrl_name = "internal",
38}; 79};
@@ -62,6 +103,7 @@ static void __init rx51_init_irq(void)
62 103
63 omap_board_config = rx51_config; 104 omap_board_config = rx51_config;
64 omap_board_config_size = ARRAY_SIZE(rx51_config); 105 omap_board_config_size = ARRAY_SIZE(rx51_config);
106 omap3_pm_init_cpuidle(rx51_cpuidle_params);
65 sdrc_params = rx51_get_sdram_timings(); 107 sdrc_params = rx51_get_sdram_timings();
66 omap2_init_common_hw(sdrc_params, sdrc_params); 108 omap2_init_common_hw(sdrc_params, sdrc_params);
67 omap_init_irq(); 109 omap_init_irq();
@@ -94,6 +136,8 @@ static void __init rx51_init(void)
94 /* Ensure SDRC pins are mux'd for self-refresh */ 136 /* Ensure SDRC pins are mux'd for self-refresh */
95 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); 137 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
96 omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); 138 omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
139
140 platform_device_register(&leds_gpio);
97} 141}
98 142
99static void __init rx51_map_io(void) 143static void __init rx51_map_io(void)
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 12f0cbfc2894..3d3d035db9af 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -45,6 +45,8 @@
45#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */ 45#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */
46#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */ 46#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */
47 47
48#define OMAP3_STATE_MAX OMAP3_STATE_C7
49
48struct omap3_processor_cx { 50struct omap3_processor_cx {
49 u8 valid; 51 u8 valid;
50 u8 type; 52 u8 type;
@@ -60,6 +62,30 @@ struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
60struct omap3_processor_cx current_cx_state; 62struct omap3_processor_cx current_cx_state;
61struct powerdomain *mpu_pd, *core_pd; 63struct powerdomain *mpu_pd, *core_pd;
62 64
65/*
66 * The latencies/thresholds for various C states have
67 * to be configured from the respective board files.
68 * These are some default values (which might not provide
69 * the best power savings) used on boards which do not
70 * pass these details from the board file.
71 */
72static struct cpuidle_params cpuidle_params_table[] = {
73 /* C1 */
74 {1, 2, 2, 5},
75 /* C2 */
76 {1, 10, 10, 30},
77 /* C3 */
78 {1, 50, 50, 300},
79 /* C4 */
80 {1, 1500, 1800, 4000},
81 /* C5 */
82 {1, 2500, 7500, 12000},
83 /* C6 */
84 {1, 3000, 8500, 15000},
85 /* C7 */
86 {1, 10000, 30000, 300000},
87};
88
63static int omap3_idle_bm_check(void) 89static int omap3_idle_bm_check(void)
64{ 90{
65 if (!omap3_can_sleep()) 91 if (!omap3_can_sleep())
@@ -104,13 +130,6 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
104 local_irq_disable(); 130 local_irq_disable();
105 local_fiq_disable(); 131 local_fiq_disable();
106 132
107 if (!enable_off_mode) {
108 if (mpu_state < PWRDM_POWER_RET)
109 mpu_state = PWRDM_POWER_RET;
110 if (core_state < PWRDM_POWER_RET)
111 core_state = PWRDM_POWER_RET;
112 }
113
114 pwrdm_set_next_pwrst(mpu_pd, mpu_state); 133 pwrdm_set_next_pwrst(mpu_pd, mpu_state);
115 pwrdm_set_next_pwrst(core_pd, core_state); 134 pwrdm_set_next_pwrst(core_pd, core_state);
116 135
@@ -141,6 +160,67 @@ return_sleep_time:
141} 160}
142 161
143/** 162/**
163 * next_valid_state - Find next valid c-state
164 * @dev: cpuidle device
165 * @state: Currently selected c-state
166 *
167 * If the current state is valid, it is returned back to the caller.
168 * Else, this function searches for a lower c-state which is still
169 * valid (as defined in omap3_power_states[]).
170 */
171static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
172 struct cpuidle_state *curr)
173{
174 struct cpuidle_state *next = NULL;
175 struct omap3_processor_cx *cx;
176
177 cx = (struct omap3_processor_cx *)cpuidle_get_statedata(curr);
178
179 /* Check if current state is valid */
180 if (cx->valid) {
181 return curr;
182 } else {
183 u8 idx = OMAP3_STATE_MAX;
184
185 /*
186 * Reach the current state starting at highest C-state
187 */
188 for (; idx >= OMAP3_STATE_C1; idx--) {
189 if (&dev->states[idx] == curr) {
190 next = &dev->states[idx];
191 break;
192 }
193 }
194
195 /*
196 * Should never hit this condition.
197 */
198 WARN_ON(next == NULL);
199
200 /*
201 * Drop to next valid state.
202 * Start search from the next (lower) state.
203 */
204 idx--;
205 for (; idx >= OMAP3_STATE_C1; idx--) {
206 struct omap3_processor_cx *cx;
207
208 cx = cpuidle_get_statedata(&dev->states[idx]);
209 if (cx->valid) {
210 next = &dev->states[idx];
211 break;
212 }
213 }
214 /*
215 * C1 and C2 are always valid.
216 * So, no need to check for 'next==NULL' outside this loop.
217 */
218 }
219
220 return next;
221}
222
223/**
144 * omap3_enter_idle_bm - Checks for any bus activity 224 * omap3_enter_idle_bm - Checks for any bus activity
145 * @dev: cpuidle device 225 * @dev: cpuidle device
146 * @state: The target state to be programmed 226 * @state: The target state to be programmed
@@ -152,7 +232,7 @@ return_sleep_time:
152static int omap3_enter_idle_bm(struct cpuidle_device *dev, 232static int omap3_enter_idle_bm(struct cpuidle_device *dev,
153 struct cpuidle_state *state) 233 struct cpuidle_state *state)
154{ 234{
155 struct cpuidle_state *new_state = state; 235 struct cpuidle_state *new_state = next_valid_state(dev, state);
156 236
157 if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) { 237 if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
158 BUG_ON(!dev->safe_state); 238 BUG_ON(!dev->safe_state);
@@ -165,6 +245,50 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
165 245
166DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); 246DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
167 247
248/**
249 * omap3_cpuidle_update_states - Update the cpuidle states.
250 *
251 * Currently, this function toggles the validity of idle states based upon
252 * the flag 'enable_off_mode'. When the flag is set all states are valid.
253 * Else, states leading to OFF state set to be invalid.
254 */
255void omap3_cpuidle_update_states(void)
256{
257 int i;
258
259 for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
260 struct omap3_processor_cx *cx = &omap3_power_states[i];
261
262 if (enable_off_mode) {
263 cx->valid = 1;
264 } else {
265 if ((cx->mpu_state == PWRDM_POWER_OFF) ||
266 (cx->core_state == PWRDM_POWER_OFF))
267 cx->valid = 0;
268 }
269 }
270}
271
272void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
273{
274 int i;
275
276 if (!cpuidle_board_params)
277 return;
278
279 for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
280 cpuidle_params_table[i].valid =
281 cpuidle_board_params[i].valid;
282 cpuidle_params_table[i].sleep_latency =
283 cpuidle_board_params[i].sleep_latency;
284 cpuidle_params_table[i].wake_latency =
285 cpuidle_board_params[i].wake_latency;
286 cpuidle_params_table[i].threshold =
287 cpuidle_board_params[i].threshold;
288 }
289 return;
290}
291
168/* omap3_init_power_states - Initialises the OMAP3 specific C states. 292/* omap3_init_power_states - Initialises the OMAP3 specific C states.
169 * 293 *
170 * Below is the desciption of each C state. 294 * Below is the desciption of each C state.
@@ -179,75 +303,103 @@ DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
179void omap_init_power_states(void) 303void omap_init_power_states(void)
180{ 304{
181 /* C1 . MPU WFI + Core active */ 305 /* C1 . MPU WFI + Core active */
182 omap3_power_states[OMAP3_STATE_C1].valid = 1; 306 omap3_power_states[OMAP3_STATE_C1].valid =
307 cpuidle_params_table[OMAP3_STATE_C1].valid;
183 omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1; 308 omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1;
184 omap3_power_states[OMAP3_STATE_C1].sleep_latency = 2; 309 omap3_power_states[OMAP3_STATE_C1].sleep_latency =
185 omap3_power_states[OMAP3_STATE_C1].wakeup_latency = 2; 310 cpuidle_params_table[OMAP3_STATE_C1].sleep_latency;
186 omap3_power_states[OMAP3_STATE_C1].threshold = 5; 311 omap3_power_states[OMAP3_STATE_C1].wakeup_latency =
312 cpuidle_params_table[OMAP3_STATE_C1].wake_latency;
313 omap3_power_states[OMAP3_STATE_C1].threshold =
314 cpuidle_params_table[OMAP3_STATE_C1].threshold;
187 omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON; 315 omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON;
188 omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON; 316 omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON;
189 omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID; 317 omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID;
190 318
191 /* C2 . MPU WFI + Core inactive */ 319 /* C2 . MPU WFI + Core inactive */
192 omap3_power_states[OMAP3_STATE_C2].valid = 1; 320 omap3_power_states[OMAP3_STATE_C2].valid =
321 cpuidle_params_table[OMAP3_STATE_C2].valid;
193 omap3_power_states[OMAP3_STATE_C2].type = OMAP3_STATE_C2; 322 omap3_power_states[OMAP3_STATE_C2].type = OMAP3_STATE_C2;
194 omap3_power_states[OMAP3_STATE_C2].sleep_latency = 10; 323 omap3_power_states[OMAP3_STATE_C2].sleep_latency =
195 omap3_power_states[OMAP3_STATE_C2].wakeup_latency = 10; 324 cpuidle_params_table[OMAP3_STATE_C2].sleep_latency;
196 omap3_power_states[OMAP3_STATE_C2].threshold = 30; 325 omap3_power_states[OMAP3_STATE_C2].wakeup_latency =
326 cpuidle_params_table[OMAP3_STATE_C2].wake_latency;
327 omap3_power_states[OMAP3_STATE_C2].threshold =
328 cpuidle_params_table[OMAP3_STATE_C2].threshold;
197 omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON; 329 omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON;
198 omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON; 330 omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON;
199 omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID; 331 omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
200 332
201 /* C3 . MPU CSWR + Core inactive */ 333 /* C3 . MPU CSWR + Core inactive */
202 omap3_power_states[OMAP3_STATE_C3].valid = 1; 334 omap3_power_states[OMAP3_STATE_C3].valid =
335 cpuidle_params_table[OMAP3_STATE_C3].valid;
203 omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3; 336 omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3;
204 omap3_power_states[OMAP3_STATE_C3].sleep_latency = 50; 337 omap3_power_states[OMAP3_STATE_C3].sleep_latency =
205 omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 50; 338 cpuidle_params_table[OMAP3_STATE_C3].sleep_latency;
206 omap3_power_states[OMAP3_STATE_C3].threshold = 300; 339 omap3_power_states[OMAP3_STATE_C3].wakeup_latency =
340 cpuidle_params_table[OMAP3_STATE_C3].wake_latency;
341 omap3_power_states[OMAP3_STATE_C3].threshold =
342 cpuidle_params_table[OMAP3_STATE_C3].threshold;
207 omap3_power_states[OMAP3_STATE_C3].mpu_state = PWRDM_POWER_RET; 343 omap3_power_states[OMAP3_STATE_C3].mpu_state = PWRDM_POWER_RET;
208 omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON; 344 omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON;
209 omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID | 345 omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID |
210 CPUIDLE_FLAG_CHECK_BM; 346 CPUIDLE_FLAG_CHECK_BM;
211 347
212 /* C4 . MPU OFF + Core inactive */ 348 /* C4 . MPU OFF + Core inactive */
213 omap3_power_states[OMAP3_STATE_C4].valid = 1; 349 omap3_power_states[OMAP3_STATE_C4].valid =
350 cpuidle_params_table[OMAP3_STATE_C4].valid;
214 omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4; 351 omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4;
215 omap3_power_states[OMAP3_STATE_C4].sleep_latency = 1500; 352 omap3_power_states[OMAP3_STATE_C4].sleep_latency =
216 omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 1800; 353 cpuidle_params_table[OMAP3_STATE_C4].sleep_latency;
217 omap3_power_states[OMAP3_STATE_C4].threshold = 4000; 354 omap3_power_states[OMAP3_STATE_C4].wakeup_latency =
355 cpuidle_params_table[OMAP3_STATE_C4].wake_latency;
356 omap3_power_states[OMAP3_STATE_C4].threshold =
357 cpuidle_params_table[OMAP3_STATE_C4].threshold;
218 omap3_power_states[OMAP3_STATE_C4].mpu_state = PWRDM_POWER_OFF; 358 omap3_power_states[OMAP3_STATE_C4].mpu_state = PWRDM_POWER_OFF;
219 omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_ON; 359 omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_ON;
220 omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID | 360 omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID |
221 CPUIDLE_FLAG_CHECK_BM; 361 CPUIDLE_FLAG_CHECK_BM;
222 362
223 /* C5 . MPU CSWR + Core CSWR*/ 363 /* C5 . MPU CSWR + Core CSWR*/
224 omap3_power_states[OMAP3_STATE_C5].valid = 1; 364 omap3_power_states[OMAP3_STATE_C5].valid =
365 cpuidle_params_table[OMAP3_STATE_C5].valid;
225 omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5; 366 omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5;
226 omap3_power_states[OMAP3_STATE_C5].sleep_latency = 2500; 367 omap3_power_states[OMAP3_STATE_C5].sleep_latency =
227 omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 7500; 368 cpuidle_params_table[OMAP3_STATE_C5].sleep_latency;
228 omap3_power_states[OMAP3_STATE_C5].threshold = 12000; 369 omap3_power_states[OMAP3_STATE_C5].wakeup_latency =
370 cpuidle_params_table[OMAP3_STATE_C5].wake_latency;
371 omap3_power_states[OMAP3_STATE_C5].threshold =
372 cpuidle_params_table[OMAP3_STATE_C5].threshold;
229 omap3_power_states[OMAP3_STATE_C5].mpu_state = PWRDM_POWER_RET; 373 omap3_power_states[OMAP3_STATE_C5].mpu_state = PWRDM_POWER_RET;
230 omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET; 374 omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET;
231 omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID | 375 omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID |
232 CPUIDLE_FLAG_CHECK_BM; 376 CPUIDLE_FLAG_CHECK_BM;
233 377
234 /* C6 . MPU OFF + Core CSWR */ 378 /* C6 . MPU OFF + Core CSWR */
235 omap3_power_states[OMAP3_STATE_C6].valid = 1; 379 omap3_power_states[OMAP3_STATE_C6].valid =
380 cpuidle_params_table[OMAP3_STATE_C6].valid;
236 omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6; 381 omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6;
237 omap3_power_states[OMAP3_STATE_C6].sleep_latency = 3000; 382 omap3_power_states[OMAP3_STATE_C6].sleep_latency =
238 omap3_power_states[OMAP3_STATE_C6].wakeup_latency = 8500; 383 cpuidle_params_table[OMAP3_STATE_C6].sleep_latency;
239 omap3_power_states[OMAP3_STATE_C6].threshold = 15000; 384 omap3_power_states[OMAP3_STATE_C6].wakeup_latency =
385 cpuidle_params_table[OMAP3_STATE_C6].wake_latency;
386 omap3_power_states[OMAP3_STATE_C6].threshold =
387 cpuidle_params_table[OMAP3_STATE_C6].threshold;
240 omap3_power_states[OMAP3_STATE_C6].mpu_state = PWRDM_POWER_OFF; 388 omap3_power_states[OMAP3_STATE_C6].mpu_state = PWRDM_POWER_OFF;
241 omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_RET; 389 omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_RET;
242 omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID | 390 omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID |
243 CPUIDLE_FLAG_CHECK_BM; 391 CPUIDLE_FLAG_CHECK_BM;
244 392
245 /* C7 . MPU OFF + Core OFF */ 393 /* C7 . MPU OFF + Core OFF */
246 omap3_power_states[OMAP3_STATE_C7].valid = 1; 394 omap3_power_states[OMAP3_STATE_C7].valid =
395 cpuidle_params_table[OMAP3_STATE_C7].valid;
247 omap3_power_states[OMAP3_STATE_C7].type = OMAP3_STATE_C7; 396 omap3_power_states[OMAP3_STATE_C7].type = OMAP3_STATE_C7;
248 omap3_power_states[OMAP3_STATE_C7].sleep_latency = 10000; 397 omap3_power_states[OMAP3_STATE_C7].sleep_latency =
249 omap3_power_states[OMAP3_STATE_C7].wakeup_latency = 30000; 398 cpuidle_params_table[OMAP3_STATE_C7].sleep_latency;
250 omap3_power_states[OMAP3_STATE_C7].threshold = 300000; 399 omap3_power_states[OMAP3_STATE_C7].wakeup_latency =
400 cpuidle_params_table[OMAP3_STATE_C7].wake_latency;
401 omap3_power_states[OMAP3_STATE_C7].threshold =
402 cpuidle_params_table[OMAP3_STATE_C7].threshold;
251 omap3_power_states[OMAP3_STATE_C7].mpu_state = PWRDM_POWER_OFF; 403 omap3_power_states[OMAP3_STATE_C7].mpu_state = PWRDM_POWER_OFF;
252 omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF; 404 omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF;
253 omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID | 405 omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID |
@@ -302,6 +454,8 @@ int __init omap3_idle_init(void)
302 return -EINVAL; 454 return -EINVAL;
303 dev->state_count = count; 455 dev->state_count = count;
304 456
457 omap3_cpuidle_update_states();
458
305 if (cpuidle_register_device(dev)) { 459 if (cpuidle_register_device(dev)) {
306 printk(KERN_ERR "%s: CPUidle register device failed\n", 460 printk(KERN_ERR "%s: CPUidle register device failed\n",
307 __func__); 461 __func__);
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 7a9c2d004511..bd6466a2b039 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -23,6 +23,22 @@ extern int omap3_can_sleep(void);
23extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); 23extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
24extern int omap3_idle_init(void); 24extern int omap3_idle_init(void);
25 25
26struct cpuidle_params {
27 u8 valid;
28 u32 sleep_latency;
29 u32 wake_latency;
30 u32 threshold;
31};
32
33#if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE)
34extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params);
35#else
36static
37inline void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
38{
39}
40#endif
41
26extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); 42extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
27extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); 43extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
28 44
@@ -37,6 +53,10 @@ extern int omap2_pm_debug;
37#define omap2_pm_debug 0 53#define omap2_pm_debug 0
38#endif 54#endif
39 55
56#if defined(CONFIG_CPU_IDLE)
57extern void omap3_cpuidle_update_states(void);
58#endif
59
40#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) 60#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
41extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev); 61extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
42extern int pm_dbg_regset_save(int reg_set); 62extern int pm_dbg_regset_save(int reg_set);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 5087b153b093..5320229926e4 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -941,6 +941,10 @@ void omap3_pm_off_mode_enable(int enable)
941 else 941 else
942 state = PWRDM_POWER_RET; 942 state = PWRDM_POWER_RET;
943 943
944#ifdef CONFIG_CPU_IDLE
945 omap3_cpuidle_update_states();
946#endif
947
944 list_for_each_entry(pwrst, &pwrst_list, node) { 948 list_for_each_entry(pwrst, &pwrst_list, node) {
945 pwrst->next_state = state; 949 pwrst->next_state = state;
946 set_pwrdm_state(pwrst->pwrdm, state); 950 set_pwrdm_state(pwrst->pwrdm, state);
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 22fcc14e63be..d522cd70bf53 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -33,6 +33,8 @@
33#include "prm.h" 33#include "prm.h"
34#include "sdrc.h" 34#include "sdrc.h"
35 35
36#define SDRC_SCRATCHPAD_SEM_V 0xfa00291c
37
36#define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \ 38#define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
37 OMAP3430_PM_PREPWSTST) 39 OMAP3430_PM_PREPWSTST)
38#define PM_PREPWSTST_CORE_P 0x48306AE8 40#define PM_PREPWSTST_CORE_P 0x48306AE8
@@ -57,6 +59,37 @@
57#define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) 59#define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
58#define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) 60#define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
59 61
62 .text
63/* Function to aquire the semaphore in scratchpad */
64ENTRY(lock_scratchpad_sem)
65 stmfd sp!, {lr} @ save registers on stack
66wait_sem:
67 mov r0,#1
68 ldr r1, sdrc_scratchpad_sem
69wait_loop:
70 ldr r2, [r1] @ load the lock value
71 cmp r2, r0 @ is the lock free ?
72 beq wait_loop @ not free...
73 swp r2, r0, [r1] @ semaphore free so lock it and proceed
74 cmp r2, r0 @ did we succeed ?
75 beq wait_sem @ no - try again
76 ldmfd sp!, {pc} @ restore regs and return
77sdrc_scratchpad_sem:
78 .word SDRC_SCRATCHPAD_SEM_V
79ENTRY(lock_scratchpad_sem_sz)
80 .word . - lock_scratchpad_sem
81
82 .text
83/* Function to release the scratchpad semaphore */
84ENTRY(unlock_scratchpad_sem)
85 stmfd sp!, {lr} @ save registers on stack
86 ldr r3, sdrc_scratchpad_sem
87 mov r2,#0
88 str r2,[r3]
89 ldmfd sp!, {pc} @ restore regs and return
90ENTRY(unlock_scratchpad_sem_sz)
91 .word . - unlock_scratchpad_sem
92
60 .text 93 .text
61/* Function call to get the restore pointer for resume from OFF */ 94/* Function call to get the restore pointer for resume from OFF */
62ENTRY(get_restore_pointer) 95ENTRY(get_restore_pointer)
@@ -251,6 +284,21 @@ restore:
251 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier 284 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
252 .word 0xE1600071 @ call SMI monitor (smi #1) 285 .word 0xE1600071 @ call SMI monitor (smi #1)
253 286
287#ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE
288 /* Restore L2 aux control register */
289 @ set service ID for PPA
290 mov r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
291 mov r12, r0 @ copy service ID in r12
292 mov r1, #0 @ set task ID for ROM code in r1
293 mov r2, #4 @ set some flags in r2, r6
294 mov r6, #0xff
295 ldr r4, scratchpad_base
296 ldr r3, [r4, #0xBC]
297 adds r3, r3, #8 @ r3 points to parameters
298 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
299 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
300 .word 0xE1600071 @ call SMI monitor (smi #1)
301#endif
254 b logic_l1_restore 302 b logic_l1_restore
255l2_inv_api_params: 303l2_inv_api_params:
256 .word 0x1, 0x00 304 .word 0x1, 0x00
@@ -264,6 +312,11 @@ smi: .word 0xE1600070 @ Call SMI monitor (smieq)
264 ldr r0, [r3,#4] 312 ldr r0, [r3,#4]
265 mov r12, #0x3 313 mov r12, #0x3
266 .word 0xE1600070 @ Call SMI monitor (smieq) 314 .word 0xE1600070 @ Call SMI monitor (smieq)
315 ldr r4, scratchpad_base
316 ldr r3, [r4,#0xBC]
317 ldr r0, [r3,#12]
318 mov r12, #0x2
319 .word 0xE1600070 @ Call SMI monitor (smieq)
267logic_l1_restore: 320logic_l1_restore:
268 mov r1, #0 321 mov r1, #0
269 /* Invalidate all instruction caches to PoU 322 /* Invalidate all instruction caches to PoU
@@ -272,7 +325,7 @@ logic_l1_restore:
272 325
273 ldr r4, scratchpad_base 326 ldr r4, scratchpad_base
274 ldr r3, [r4,#0xBC] 327 ldr r3, [r4,#0xBC]
275 adds r3, r3, #8 328 adds r3, r3, #16
276 ldmia r3!, {r4-r6} 329 ldmia r3!, {r4-r6}
277 mov sp, r4 330 mov sp, r4
278 msr spsr_cxsf, r5 331 msr spsr_cxsf, r5
@@ -391,7 +444,9 @@ save_context_wfi:
391 mov r8, r0 /* Store SDRAM address in r8 */ 444 mov r8, r0 /* Store SDRAM address in r8 */
392 mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register 445 mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register
393 mov r4, #0x1 @ Number of parameters for restore call 446 mov r4, #0x1 @ Number of parameters for restore call
394 stmia r8!, {r4-r5} 447 stmia r8!, {r4-r5} @ Push parameters for restore call
448 mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register
449 stmia r8!, {r4-r5} @ Push parameters for restore call
395 /* Check what that target sleep state is:stored in r1*/ 450 /* Check what that target sleep state is:stored in r1*/
396 /* 1 - Only L1 and logic lost */ 451 /* 1 - Only L1 and logic lost */
397 /* 2 - Only L2 lost */ 452 /* 2 - Only L2 lost */
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 97d0c79ffd2b..be9484a28b12 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -135,6 +135,23 @@ config OMAP_32K_TIMER
135 135
136endchoice 136endchoice
137 137
138config OMAP3_L2_AUX_SECURE_SAVE_RESTORE
139 bool "OMAP3 HS/EMU save and restore for L2 AUX control register"
140 depends on ARCH_OMAP3 && PM
141 default n
142 help
143 Without this option, L2 Auxiliary control register contents are
144 lost during off-mode entry on HS/EMU devices. This feature
145 requires support from PPA / boot-loader in HS/EMU devices, which
146 currently does not exist by default.
147
148config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
149 int "Service ID for the support routine to set L2 AUX control"
150 depends on OMAP3_L2_AUX_SECURE_SAVE_RESTORE
151 default 43
152 help
153 PPA routine service ID for setting L2 auxiliary control register.
154
138config OMAP_32K_TIMER_HZ 155config OMAP_32K_TIMER_HZ
139 int "Kernel internal timer frequency for 32KHz timer" 156 int "Kernel internal timer frequency for 32KHz timer"
140 range 32 1024 157 range 32 1024