Commit 0fdc54b2 authored by Tony Lindgren's avatar Tony Lindgren

Merge branch 'pm-2.6.34' of...

Merge branch 'pm-2.6.34' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
parents 8250a5c3 79dcfdd4
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment