mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
Merge branch 'pm-2.6.34' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
This commit is contained in:
commit
0fdc54b201
7 changed files with 352 additions and 38 deletions
|
@ -46,6 +46,7 @@
|
|||
#include "mux.h"
|
||||
#include "sdram-qimonda-hyb18m512160af-6.h"
|
||||
#include "hsmmc.h"
|
||||
#include "pm.h"
|
||||
|
||||
#define CONFIG_DISABLE_HFCLK 1
|
||||
|
||||
|
@ -57,6 +58,24 @@
|
|||
|
||||
#define TWL4030_MSECURE_GPIO 22
|
||||
|
||||
/* FIXME: These values need to be updated based on more profiling on 3430sdp*/
|
||||
static struct cpuidle_params omap3_cpuidle_params_table[] = {
|
||||
/* C1 */
|
||||
{1, 2, 2, 5},
|
||||
/* C2 */
|
||||
{1, 10, 10, 30},
|
||||
/* C3 */
|
||||
{1, 50, 50, 300},
|
||||
/* C4 */
|
||||
{1, 1500, 1800, 4000},
|
||||
/* C5 */
|
||||
{1, 2500, 7500, 12000},
|
||||
/* C6 */
|
||||
{1, 3000, 8500, 15000},
|
||||
/* C7 */
|
||||
{1, 10000, 30000, 300000},
|
||||
};
|
||||
|
||||
static int board_keymap[] = {
|
||||
KEY(0, 0, KEY_LEFT),
|
||||
KEY(0, 1, KEY_RIGHT),
|
||||
|
@ -307,6 +326,7 @@ static void __init omap_3430sdp_init_irq(void)
|
|||
{
|
||||
omap_board_config = sdp3430_config;
|
||||
omap_board_config_size = ARRAY_SIZE(sdp3430_config);
|
||||
omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
|
||||
omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
|
||||
omap_init_irq();
|
||||
omap_gpio_init();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
@ -30,9 +31,49 @@
|
|||
#include <plat/usb.h>
|
||||
|
||||
#include "mux.h"
|
||||
#include "pm.h"
|
||||
|
||||
#define RX51_GPIO_SLEEP_IND 162
|
||||
|
||||
struct omap_sdrc_params *rx51_get_sdram_timings(void);
|
||||
|
||||
static struct gpio_led gpio_leds[] = {
|
||||
{
|
||||
.name = "sleep_ind",
|
||||
.gpio = RX51_GPIO_SLEEP_IND,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data gpio_led_info = {
|
||||
.leds = gpio_leds,
|
||||
.num_leds = ARRAY_SIZE(gpio_leds),
|
||||
};
|
||||
|
||||
static struct platform_device leds_gpio = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &gpio_led_info,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cpuidle_params rx51_cpuidle_params[] = {
|
||||
/* C1 */
|
||||
{1, 110, 162, 5},
|
||||
/* C2 */
|
||||
{1, 106, 180, 309},
|
||||
/* C3 */
|
||||
{0, 107, 410, 46057},
|
||||
/* C4 */
|
||||
{0, 121, 3374, 46057},
|
||||
/* C5 */
|
||||
{1, 855, 1146, 46057},
|
||||
/* C6 */
|
||||
{0, 7580, 4134, 484329},
|
||||
/* C7 */
|
||||
{1, 7505, 15274, 484329},
|
||||
};
|
||||
|
||||
static struct omap_lcd_config rx51_lcd_config = {
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
@ -62,6 +103,7 @@ static void __init rx51_init_irq(void)
|
|||
|
||||
omap_board_config = rx51_config;
|
||||
omap_board_config_size = ARRAY_SIZE(rx51_config);
|
||||
omap3_pm_init_cpuidle(rx51_cpuidle_params);
|
||||
sdrc_params = rx51_get_sdram_timings();
|
||||
omap2_init_common_hw(sdrc_params, sdrc_params);
|
||||
omap_init_irq();
|
||||
|
@ -94,6 +136,8 @@ static void __init rx51_init(void)
|
|||
/* Ensure SDRC pins are mux'd for self-refresh */
|
||||
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
|
||||
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
|
||||
|
||||
platform_device_register(&leds_gpio);
|
||||
}
|
||||
|
||||
static void __init rx51_map_io(void)
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */
|
||||
#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */
|
||||
|
||||
#define OMAP3_STATE_MAX OMAP3_STATE_C7
|
||||
|
||||
struct omap3_processor_cx {
|
||||
u8 valid;
|
||||
u8 type;
|
||||
|
@ -60,6 +62,30 @@ struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
|
|||
struct omap3_processor_cx current_cx_state;
|
||||
struct powerdomain *mpu_pd, *core_pd;
|
||||
|
||||
/*
|
||||
* The latencies/thresholds for various C states have
|
||||
* to be configured from the respective board files.
|
||||
* These are some default values (which might not provide
|
||||
* the best power savings) used on boards which do not
|
||||
* pass these details from the board file.
|
||||
*/
|
||||
static struct cpuidle_params cpuidle_params_table[] = {
|
||||
/* C1 */
|
||||
{1, 2, 2, 5},
|
||||
/* C2 */
|
||||
{1, 10, 10, 30},
|
||||
/* C3 */
|
||||
{1, 50, 50, 300},
|
||||
/* C4 */
|
||||
{1, 1500, 1800, 4000},
|
||||
/* C5 */
|
||||
{1, 2500, 7500, 12000},
|
||||
/* C6 */
|
||||
{1, 3000, 8500, 15000},
|
||||
/* C7 */
|
||||
{1, 10000, 30000, 300000},
|
||||
};
|
||||
|
||||
static int omap3_idle_bm_check(void)
|
||||
{
|
||||
if (!omap3_can_sleep())
|
||||
|
@ -104,13 +130,6 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
|
|||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
|
||||
if (!enable_off_mode) {
|
||||
if (mpu_state < PWRDM_POWER_RET)
|
||||
mpu_state = PWRDM_POWER_RET;
|
||||
if (core_state < PWRDM_POWER_RET)
|
||||
core_state = PWRDM_POWER_RET;
|
||||
}
|
||||
|
||||
pwrdm_set_next_pwrst(mpu_pd, mpu_state);
|
||||
pwrdm_set_next_pwrst(core_pd, core_state);
|
||||
|
||||
|
@ -140,6 +159,67 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
|
|||
return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* next_valid_state - Find next valid c-state
|
||||
* @dev: cpuidle device
|
||||
* @state: Currently selected c-state
|
||||
*
|
||||
* If the current state is valid, it is returned back to the caller.
|
||||
* Else, this function searches for a lower c-state which is still
|
||||
* valid (as defined in omap3_power_states[]).
|
||||
*/
|
||||
static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
|
||||
struct cpuidle_state *curr)
|
||||
{
|
||||
struct cpuidle_state *next = NULL;
|
||||
struct omap3_processor_cx *cx;
|
||||
|
||||
cx = (struct omap3_processor_cx *)cpuidle_get_statedata(curr);
|
||||
|
||||
/* Check if current state is valid */
|
||||
if (cx->valid) {
|
||||
return curr;
|
||||
} else {
|
||||
u8 idx = OMAP3_STATE_MAX;
|
||||
|
||||
/*
|
||||
* Reach the current state starting at highest C-state
|
||||
*/
|
||||
for (; idx >= OMAP3_STATE_C1; idx--) {
|
||||
if (&dev->states[idx] == curr) {
|
||||
next = &dev->states[idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Should never hit this condition.
|
||||
*/
|
||||
WARN_ON(next == NULL);
|
||||
|
||||
/*
|
||||
* Drop to next valid state.
|
||||
* Start search from the next (lower) state.
|
||||
*/
|
||||
idx--;
|
||||
for (; idx >= OMAP3_STATE_C1; idx--) {
|
||||
struct omap3_processor_cx *cx;
|
||||
|
||||
cx = cpuidle_get_statedata(&dev->states[idx]);
|
||||
if (cx->valid) {
|
||||
next = &dev->states[idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* C1 and C2 are always valid.
|
||||
* So, no need to check for 'next==NULL' outside this loop.
|
||||
*/
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap3_enter_idle_bm - Checks for any bus activity
|
||||
* @dev: cpuidle device
|
||||
|
@ -152,7 +232,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
|
|||
static int omap3_enter_idle_bm(struct cpuidle_device *dev,
|
||||
struct cpuidle_state *state)
|
||||
{
|
||||
struct cpuidle_state *new_state = state;
|
||||
struct cpuidle_state *new_state = next_valid_state(dev, state);
|
||||
|
||||
if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
|
||||
BUG_ON(!dev->safe_state);
|
||||
|
@ -165,6 +245,50 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
|
|||
|
||||
DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
|
||||
|
||||
/**
|
||||
* omap3_cpuidle_update_states - Update the cpuidle states.
|
||||
*
|
||||
* Currently, this function toggles the validity of idle states based upon
|
||||
* the flag 'enable_off_mode'. When the flag is set all states are valid.
|
||||
* Else, states leading to OFF state set to be invalid.
|
||||
*/
|
||||
void omap3_cpuidle_update_states(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
|
||||
struct omap3_processor_cx *cx = &omap3_power_states[i];
|
||||
|
||||
if (enable_off_mode) {
|
||||
cx->valid = 1;
|
||||
} else {
|
||||
if ((cx->mpu_state == PWRDM_POWER_OFF) ||
|
||||
(cx->core_state == PWRDM_POWER_OFF))
|
||||
cx->valid = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!cpuidle_board_params)
|
||||
return;
|
||||
|
||||
for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
|
||||
cpuidle_params_table[i].valid =
|
||||
cpuidle_board_params[i].valid;
|
||||
cpuidle_params_table[i].sleep_latency =
|
||||
cpuidle_board_params[i].sleep_latency;
|
||||
cpuidle_params_table[i].wake_latency =
|
||||
cpuidle_board_params[i].wake_latency;
|
||||
cpuidle_params_table[i].threshold =
|
||||
cpuidle_board_params[i].threshold;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* omap3_init_power_states - Initialises the OMAP3 specific C states.
|
||||
*
|
||||
* Below is the desciption of each C state.
|
||||
|
@ -179,75 +303,103 @@ DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
|
|||
void omap_init_power_states(void)
|
||||
{
|
||||
/* C1 . MPU WFI + Core active */
|
||||
omap3_power_states[OMAP3_STATE_C1].valid = 1;
|
||||
omap3_power_states[OMAP3_STATE_C1].valid =
|
||||
cpuidle_params_table[OMAP3_STATE_C1].valid;
|
||||
omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1;
|
||||
omap3_power_states[OMAP3_STATE_C1].sleep_latency = 2;
|
||||
omap3_power_states[OMAP3_STATE_C1].wakeup_latency = 2;
|
||||
omap3_power_states[OMAP3_STATE_C1].threshold = 5;
|
||||
omap3_power_states[OMAP3_STATE_C1].sleep_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C1].sleep_latency;
|
||||
omap3_power_states[OMAP3_STATE_C1].wakeup_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C1].wake_latency;
|
||||
omap3_power_states[OMAP3_STATE_C1].threshold =
|
||||
cpuidle_params_table[OMAP3_STATE_C1].threshold;
|
||||
omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON;
|
||||
omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON;
|
||||
omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID;
|
||||
|
||||
/* C2 . MPU WFI + Core inactive */
|
||||
omap3_power_states[OMAP3_STATE_C2].valid = 1;
|
||||
omap3_power_states[OMAP3_STATE_C2].valid =
|
||||
cpuidle_params_table[OMAP3_STATE_C2].valid;
|
||||
omap3_power_states[OMAP3_STATE_C2].type = OMAP3_STATE_C2;
|
||||
omap3_power_states[OMAP3_STATE_C2].sleep_latency = 10;
|
||||
omap3_power_states[OMAP3_STATE_C2].wakeup_latency = 10;
|
||||
omap3_power_states[OMAP3_STATE_C2].threshold = 30;
|
||||
omap3_power_states[OMAP3_STATE_C2].sleep_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C2].sleep_latency;
|
||||
omap3_power_states[OMAP3_STATE_C2].wakeup_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C2].wake_latency;
|
||||
omap3_power_states[OMAP3_STATE_C2].threshold =
|
||||
cpuidle_params_table[OMAP3_STATE_C2].threshold;
|
||||
omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON;
|
||||
omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON;
|
||||
omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
|
||||
|
||||
/* C3 . MPU CSWR + Core inactive */
|
||||
omap3_power_states[OMAP3_STATE_C3].valid = 1;
|
||||
omap3_power_states[OMAP3_STATE_C3].valid =
|
||||
cpuidle_params_table[OMAP3_STATE_C3].valid;
|
||||
omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3;
|
||||
omap3_power_states[OMAP3_STATE_C3].sleep_latency = 50;
|
||||
omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 50;
|
||||
omap3_power_states[OMAP3_STATE_C3].threshold = 300;
|
||||
omap3_power_states[OMAP3_STATE_C3].sleep_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C3].sleep_latency;
|
||||
omap3_power_states[OMAP3_STATE_C3].wakeup_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C3].wake_latency;
|
||||
omap3_power_states[OMAP3_STATE_C3].threshold =
|
||||
cpuidle_params_table[OMAP3_STATE_C3].threshold;
|
||||
omap3_power_states[OMAP3_STATE_C3].mpu_state = PWRDM_POWER_RET;
|
||||
omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON;
|
||||
omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
CPUIDLE_FLAG_CHECK_BM;
|
||||
|
||||
/* C4 . MPU OFF + Core inactive */
|
||||
omap3_power_states[OMAP3_STATE_C4].valid = 1;
|
||||
omap3_power_states[OMAP3_STATE_C4].valid =
|
||||
cpuidle_params_table[OMAP3_STATE_C4].valid;
|
||||
omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4;
|
||||
omap3_power_states[OMAP3_STATE_C4].sleep_latency = 1500;
|
||||
omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 1800;
|
||||
omap3_power_states[OMAP3_STATE_C4].threshold = 4000;
|
||||
omap3_power_states[OMAP3_STATE_C4].sleep_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C4].sleep_latency;
|
||||
omap3_power_states[OMAP3_STATE_C4].wakeup_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C4].wake_latency;
|
||||
omap3_power_states[OMAP3_STATE_C4].threshold =
|
||||
cpuidle_params_table[OMAP3_STATE_C4].threshold;
|
||||
omap3_power_states[OMAP3_STATE_C4].mpu_state = PWRDM_POWER_OFF;
|
||||
omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_ON;
|
||||
omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
CPUIDLE_FLAG_CHECK_BM;
|
||||
|
||||
/* C5 . MPU CSWR + Core CSWR*/
|
||||
omap3_power_states[OMAP3_STATE_C5].valid = 1;
|
||||
omap3_power_states[OMAP3_STATE_C5].valid =
|
||||
cpuidle_params_table[OMAP3_STATE_C5].valid;
|
||||
omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5;
|
||||
omap3_power_states[OMAP3_STATE_C5].sleep_latency = 2500;
|
||||
omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 7500;
|
||||
omap3_power_states[OMAP3_STATE_C5].threshold = 12000;
|
||||
omap3_power_states[OMAP3_STATE_C5].sleep_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C5].sleep_latency;
|
||||
omap3_power_states[OMAP3_STATE_C5].wakeup_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C5].wake_latency;
|
||||
omap3_power_states[OMAP3_STATE_C5].threshold =
|
||||
cpuidle_params_table[OMAP3_STATE_C5].threshold;
|
||||
omap3_power_states[OMAP3_STATE_C5].mpu_state = PWRDM_POWER_RET;
|
||||
omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET;
|
||||
omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
CPUIDLE_FLAG_CHECK_BM;
|
||||
|
||||
/* C6 . MPU OFF + Core CSWR */
|
||||
omap3_power_states[OMAP3_STATE_C6].valid = 1;
|
||||
omap3_power_states[OMAP3_STATE_C6].valid =
|
||||
cpuidle_params_table[OMAP3_STATE_C6].valid;
|
||||
omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6;
|
||||
omap3_power_states[OMAP3_STATE_C6].sleep_latency = 3000;
|
||||
omap3_power_states[OMAP3_STATE_C6].wakeup_latency = 8500;
|
||||
omap3_power_states[OMAP3_STATE_C6].threshold = 15000;
|
||||
omap3_power_states[OMAP3_STATE_C6].sleep_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C6].sleep_latency;
|
||||
omap3_power_states[OMAP3_STATE_C6].wakeup_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C6].wake_latency;
|
||||
omap3_power_states[OMAP3_STATE_C6].threshold =
|
||||
cpuidle_params_table[OMAP3_STATE_C6].threshold;
|
||||
omap3_power_states[OMAP3_STATE_C6].mpu_state = PWRDM_POWER_OFF;
|
||||
omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_RET;
|
||||
omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
CPUIDLE_FLAG_CHECK_BM;
|
||||
|
||||
/* C7 . MPU OFF + Core OFF */
|
||||
omap3_power_states[OMAP3_STATE_C7].valid = 1;
|
||||
omap3_power_states[OMAP3_STATE_C7].valid =
|
||||
cpuidle_params_table[OMAP3_STATE_C7].valid;
|
||||
omap3_power_states[OMAP3_STATE_C7].type = OMAP3_STATE_C7;
|
||||
omap3_power_states[OMAP3_STATE_C7].sleep_latency = 10000;
|
||||
omap3_power_states[OMAP3_STATE_C7].wakeup_latency = 30000;
|
||||
omap3_power_states[OMAP3_STATE_C7].threshold = 300000;
|
||||
omap3_power_states[OMAP3_STATE_C7].sleep_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C7].sleep_latency;
|
||||
omap3_power_states[OMAP3_STATE_C7].wakeup_latency =
|
||||
cpuidle_params_table[OMAP3_STATE_C7].wake_latency;
|
||||
omap3_power_states[OMAP3_STATE_C7].threshold =
|
||||
cpuidle_params_table[OMAP3_STATE_C7].threshold;
|
||||
omap3_power_states[OMAP3_STATE_C7].mpu_state = PWRDM_POWER_OFF;
|
||||
omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF;
|
||||
omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
|
@ -302,6 +454,8 @@ int __init omap3_idle_init(void)
|
|||
return -EINVAL;
|
||||
dev->state_count = count;
|
||||
|
||||
omap3_cpuidle_update_states();
|
||||
|
||||
if (cpuidle_register_device(dev)) {
|
||||
printk(KERN_ERR "%s: CPUidle register device failed\n",
|
||||
__func__);
|
||||
|
|
|
@ -23,6 +23,22 @@ extern int omap3_can_sleep(void);
|
|||
extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
|
||||
extern int omap3_idle_init(void);
|
||||
|
||||
struct cpuidle_params {
|
||||
u8 valid;
|
||||
u32 sleep_latency;
|
||||
u32 wake_latency;
|
||||
u32 threshold;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE)
|
||||
extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params);
|
||||
#else
|
||||
static
|
||||
inline void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
|
||||
extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
|
||||
|
||||
|
@ -37,6 +53,10 @@ extern int omap2_pm_debug;
|
|||
#define omap2_pm_debug 0
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CPU_IDLE)
|
||||
extern void omap3_cpuidle_update_states(void);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||
extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
|
||||
extern int pm_dbg_regset_save(int reg_set);
|
||||
|
|
|
@ -941,6 +941,10 @@ void omap3_pm_off_mode_enable(int enable)
|
|||
else
|
||||
state = PWRDM_POWER_RET;
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
omap3_cpuidle_update_states();
|
||||
#endif
|
||||
|
||||
list_for_each_entry(pwrst, &pwrst_list, node) {
|
||||
pwrst->next_state = state;
|
||||
set_pwrdm_state(pwrst->pwrdm, state);
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "prm.h"
|
||||
#include "sdrc.h"
|
||||
|
||||
#define SDRC_SCRATCHPAD_SEM_V 0xfa00291c
|
||||
|
||||
#define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
|
||||
OMAP3430_PM_PREPWSTST)
|
||||
#define PM_PREPWSTST_CORE_P 0x48306AE8
|
||||
|
@ -57,6 +59,37 @@
|
|||
#define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
|
||||
#define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
|
||||
|
||||
.text
|
||||
/* Function to aquire the semaphore in scratchpad */
|
||||
ENTRY(lock_scratchpad_sem)
|
||||
stmfd sp!, {lr} @ save registers on stack
|
||||
wait_sem:
|
||||
mov r0,#1
|
||||
ldr r1, sdrc_scratchpad_sem
|
||||
wait_loop:
|
||||
ldr r2, [r1] @ load the lock value
|
||||
cmp r2, r0 @ is the lock free ?
|
||||
beq wait_loop @ not free...
|
||||
swp r2, r0, [r1] @ semaphore free so lock it and proceed
|
||||
cmp r2, r0 @ did we succeed ?
|
||||
beq wait_sem @ no - try again
|
||||
ldmfd sp!, {pc} @ restore regs and return
|
||||
sdrc_scratchpad_sem:
|
||||
.word SDRC_SCRATCHPAD_SEM_V
|
||||
ENTRY(lock_scratchpad_sem_sz)
|
||||
.word . - lock_scratchpad_sem
|
||||
|
||||
.text
|
||||
/* Function to release the scratchpad semaphore */
|
||||
ENTRY(unlock_scratchpad_sem)
|
||||
stmfd sp!, {lr} @ save registers on stack
|
||||
ldr r3, sdrc_scratchpad_sem
|
||||
mov r2,#0
|
||||
str r2,[r3]
|
||||
ldmfd sp!, {pc} @ restore regs and return
|
||||
ENTRY(unlock_scratchpad_sem_sz)
|
||||
.word . - unlock_scratchpad_sem
|
||||
|
||||
.text
|
||||
/* Function call to get the restore pointer for resume from OFF */
|
||||
ENTRY(get_restore_pointer)
|
||||
|
@ -251,6 +284,21 @@ restore:
|
|||
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
|
||||
.word 0xE1600071 @ call SMI monitor (smi #1)
|
||||
|
||||
#ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE
|
||||
/* Restore L2 aux control register */
|
||||
@ set service ID for PPA
|
||||
mov r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
|
||||
mov r12, r0 @ copy service ID in r12
|
||||
mov r1, #0 @ set task ID for ROM code in r1
|
||||
mov r2, #4 @ set some flags in r2, r6
|
||||
mov r6, #0xff
|
||||
ldr r4, scratchpad_base
|
||||
ldr r3, [r4, #0xBC]
|
||||
adds r3, r3, #8 @ r3 points to parameters
|
||||
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
|
||||
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
|
||||
.word 0xE1600071 @ call SMI monitor (smi #1)
|
||||
#endif
|
||||
b logic_l1_restore
|
||||
l2_inv_api_params:
|
||||
.word 0x1, 0x00
|
||||
|
@ -264,6 +312,11 @@ smi: .word 0xE1600070 @ Call SMI monitor (smieq)
|
|||
ldr r0, [r3,#4]
|
||||
mov r12, #0x3
|
||||
.word 0xE1600070 @ Call SMI monitor (smieq)
|
||||
ldr r4, scratchpad_base
|
||||
ldr r3, [r4,#0xBC]
|
||||
ldr r0, [r3,#12]
|
||||
mov r12, #0x2
|
||||
.word 0xE1600070 @ Call SMI monitor (smieq)
|
||||
logic_l1_restore:
|
||||
mov r1, #0
|
||||
/* Invalidate all instruction caches to PoU
|
||||
|
@ -272,7 +325,7 @@ logic_l1_restore:
|
|||
|
||||
ldr r4, scratchpad_base
|
||||
ldr r3, [r4,#0xBC]
|
||||
adds r3, r3, #8
|
||||
adds r3, r3, #16
|
||||
ldmia r3!, {r4-r6}
|
||||
mov sp, r4
|
||||
msr spsr_cxsf, r5
|
||||
|
@ -391,7 +444,9 @@ save_context_wfi:
|
|||
mov r8, r0 /* Store SDRAM address in r8 */
|
||||
mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register
|
||||
mov r4, #0x1 @ Number of parameters for restore call
|
||||
stmia r8!, {r4-r5}
|
||||
stmia r8!, {r4-r5} @ Push parameters for restore call
|
||||
mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register
|
||||
stmia r8!, {r4-r5} @ Push parameters for restore call
|
||||
/* Check what that target sleep state is:stored in r1*/
|
||||
/* 1 - Only L1 and logic lost */
|
||||
/* 2 - Only L2 lost */
|
||||
|
|
|
@ -135,6 +135,23 @@ config OMAP_32K_TIMER
|
|||
|
||||
endchoice
|
||||
|
||||
config OMAP3_L2_AUX_SECURE_SAVE_RESTORE
|
||||
bool "OMAP3 HS/EMU save and restore for L2 AUX control register"
|
||||
depends on ARCH_OMAP3 && PM
|
||||
default n
|
||||
help
|
||||
Without this option, L2 Auxiliary control register contents are
|
||||
lost during off-mode entry on HS/EMU devices. This feature
|
||||
requires support from PPA / boot-loader in HS/EMU devices, which
|
||||
currently does not exist by default.
|
||||
|
||||
config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
|
||||
int "Service ID for the support routine to set L2 AUX control"
|
||||
depends on OMAP3_L2_AUX_SECURE_SAVE_RESTORE
|
||||
default 43
|
||||
help
|
||||
PPA routine service ID for setting L2 auxiliary control register.
|
||||
|
||||
config OMAP_32K_TIMER_HZ
|
||||
int "Kernel internal timer frequency for 32KHz timer"
|
||||
range 32 1024
|
||||
|
|
Loading…
Reference in a new issue