Loading arch/arm/mach-omap2/board-3430sdp.c +20 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ #include "mux.h" #include "sdram-qimonda-hyb18m512160af-6.h" #include "hsmmc.h" #include "pm.h" #define CONFIG_DISABLE_HFCLK 1 Loading @@ -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), Loading Loading @@ -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(); Loading arch/arm/mach-omap2/board-rx51.c +44 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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", }; Loading Loading @@ -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(); Loading Loading @@ -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) Loading arch/arm/mach-omap2/cpuidle34xx.c +190 −36 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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()) Loading Loading @@ -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); Loading Loading @@ -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 Loading @@ -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); Loading @@ -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. Loading @@ -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 | Loading Loading @@ -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__); Loading arch/arm/mach-omap2/pm.h +20 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading arch/arm/mach-omap2/pm34xx.c +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
arch/arm/mach-omap2/board-3430sdp.c +20 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ #include "mux.h" #include "sdram-qimonda-hyb18m512160af-6.h" #include "hsmmc.h" #include "pm.h" #define CONFIG_DISABLE_HFCLK 1 Loading @@ -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), Loading Loading @@ -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(); Loading
arch/arm/mach-omap2/board-rx51.c +44 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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", }; Loading Loading @@ -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(); Loading Loading @@ -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) Loading
arch/arm/mach-omap2/cpuidle34xx.c +190 −36 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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()) Loading Loading @@ -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); Loading Loading @@ -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 Loading @@ -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); Loading @@ -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. Loading @@ -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 | Loading Loading @@ -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__); Loading
arch/arm/mach-omap2/pm.h +20 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading
arch/arm/mach-omap2/pm34xx.c +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading