diff options
author | Tony Lindgren <tony@atomide.com> | 2010-02-23 22:22:48 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2010-02-23 22:22:48 -0500 |
commit | 0fdc54b2019700a4b50179914e810367c14044a3 (patch) | |
tree | 73e5e34f30aec87ad4bf4423c4f95ebba576359e | |
parent | 8250a5c381cc6714a061a39cfd29d7453e8ad64b (diff) | |
parent | 79dcfdd407208cba06bd446e93b0809df1cf10d1 (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.c | 20 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-rx51.c | 44 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cpuidle34xx.c | 226 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.h | 20 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap2/sleep34xx.S | 59 | ||||
-rw-r--r-- | arch/arm/plat-omap/Kconfig | 17 |
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*/ | ||
62 | static 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 | |||
60 | static int board_keymap[] = { | 79 | static 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 | ||
34 | struct omap_sdrc_params *rx51_get_sdram_timings(void); | 38 | struct omap_sdrc_params *rx51_get_sdram_timings(void); |
35 | 39 | ||
40 | static struct gpio_led gpio_leds[] = { | ||
41 | { | ||
42 | .name = "sleep_ind", | ||
43 | .gpio = RX51_GPIO_SLEEP_IND, | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | static struct gpio_led_platform_data gpio_led_info = { | ||
48 | .leds = gpio_leds, | ||
49 | .num_leds = ARRAY_SIZE(gpio_leds), | ||
50 | }; | ||
51 | |||
52 | static struct platform_device leds_gpio = { | ||
53 | .name = "leds-gpio", | ||
54 | .id = -1, | ||
55 | .dev = { | ||
56 | .platform_data = &gpio_led_info, | ||
57 | }, | ||
58 | }; | ||
59 | |||
60 | static 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 | |||
36 | static struct omap_lcd_config rx51_lcd_config = { | 77 | static 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 | ||
99 | static void __init rx51_map_io(void) | 143 | static 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 | |||
48 | struct omap3_processor_cx { | 50 | struct 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]; | |||
60 | struct omap3_processor_cx current_cx_state; | 62 | struct omap3_processor_cx current_cx_state; |
61 | struct powerdomain *mpu_pd, *core_pd; | 63 | struct 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 | */ | ||
72 | static 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 | |||
63 | static int omap3_idle_bm_check(void) | 89 | static 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 | */ | ||
171 | static 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: | |||
152 | static int omap3_enter_idle_bm(struct cpuidle_device *dev, | 232 | static 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 | ||
166 | DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); | 246 | DEFINE_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 | */ | ||
255 | void 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 | |||
272 | void 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); | |||
179 | void omap_init_power_states(void) | 303 | void 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); | |||
23 | extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); | 23 | extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); |
24 | extern int omap3_idle_init(void); | 24 | extern int omap3_idle_init(void); |
25 | 25 | ||
26 | struct 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) | ||
34 | extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params); | ||
35 | #else | ||
36 | static | ||
37 | inline void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) | ||
38 | { | ||
39 | } | ||
40 | #endif | ||
41 | |||
26 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); | 42 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); |
27 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); | 43 | extern 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) | ||
57 | extern 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) |
41 | extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev); | 61 | extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev); |
42 | extern int pm_dbg_regset_save(int reg_set); | 62 | extern 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 */ | ||
64 | ENTRY(lock_scratchpad_sem) | ||
65 | stmfd sp!, {lr} @ save registers on stack | ||
66 | wait_sem: | ||
67 | mov r0,#1 | ||
68 | ldr r1, sdrc_scratchpad_sem | ||
69 | wait_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 | ||
77 | sdrc_scratchpad_sem: | ||
78 | .word SDRC_SCRATCHPAD_SEM_V | ||
79 | ENTRY(lock_scratchpad_sem_sz) | ||
80 | .word . - lock_scratchpad_sem | ||
81 | |||
82 | .text | ||
83 | /* Function to release the scratchpad semaphore */ | ||
84 | ENTRY(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 | ||
90 | ENTRY(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 */ |
62 | ENTRY(get_restore_pointer) | 95 | ENTRY(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 |
255 | l2_inv_api_params: | 303 | l2_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) | ||
267 | logic_l1_restore: | 320 | logic_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 | ||
136 | endchoice | 136 | endchoice |
137 | 137 | ||
138 | config 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 | |||
148 | config 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 | |||
138 | config OMAP_32K_TIMER_HZ | 155 | config 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 |