Loading arch/arm/mach-omap2/board-rx51.c +18 −20 Original line number Diff line number Diff line Loading @@ -59,25 +59,24 @@ static struct platform_device leds_gpio = { }; /* * cpuidle C-states definition override from the default values. * The 'exit_latency' field is the sum of sleep and wake-up latencies. * cpuidle C-states definition for rx51. * * The 'exit_latency' field is the sum of sleep * and wake-up latencies. --------------------------------------------- | state | exit_latency | target_residency | --------------------------------------------- | C1 | 110 + 162 | 5 | | C2 | 106 + 180 | 309 | | C3 | 107 + 410 | 46057 | | C4 | 121 + 3374 | 46057 | | C5 | 855 + 1146 | 46057 | | C6 | 7580 + 4134 | 484329 | | C7 | 7505 + 15274 | 484329 | --------------------------------------------- */ static struct cpuidle_params rx51_cpuidle_params[] = { /* C1 */ {110 + 162, 5 , 1}, /* C2 */ {106 + 180, 309, 1}, /* C3 */ {107 + 410, 46057, 0}, /* C4 */ {121 + 3374, 46057, 0}, /* C5 */ {855 + 1146, 46057, 1}, /* C6 */ {7580 + 4134, 484329, 0}, /* C7 */ {7505 + 15274, 484329, 1}, }; extern void __init rx51_peripherals_init(void); Loading @@ -98,7 +97,6 @@ static void __init rx51_init(void) struct omap_sdrc_params *sdrc_params; omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3_pm_init_cpuidle(rx51_cpuidle_params); omap_serial_init(); sdrc_params = nokia_get_sdram_timings(); Loading arch/arm/mach-omap2/cpuidle34xx.c +120 −178 Original line number Diff line number Diff line Loading @@ -38,40 +38,44 @@ #ifdef CONFIG_CPU_IDLE /* * 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 */ {2 + 2, 5, 1}, /* C2 */ {10 + 10, 30, 1}, /* C3 */ {50 + 50, 300, 1}, /* C4 */ {1500 + 1800, 4000, 1}, /* C5 */ {2500 + 7500, 12000, 1}, /* C6 */ {3000 + 8500, 15000, 1}, /* C7 */ {10000 + 30000, 300000, 1}, }; #define OMAP3_NUM_STATES ARRAY_SIZE(cpuidle_params_table) /* Mach specific information to be recorded in the C-state driver_data */ struct omap3_idle_statedata { u32 mpu_state; u32 core_state; u8 valid; }; struct omap3_idle_statedata omap3_idle_data[OMAP3_NUM_STATES]; struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; static struct omap3_idle_statedata omap3_idle_data[] = { { .mpu_state = PWRDM_POWER_ON, .core_state = PWRDM_POWER_ON, }, { .mpu_state = PWRDM_POWER_ON, .core_state = PWRDM_POWER_ON, }, { .mpu_state = PWRDM_POWER_RET, .core_state = PWRDM_POWER_ON, }, { .mpu_state = PWRDM_POWER_OFF, .core_state = PWRDM_POWER_ON, }, { .mpu_state = PWRDM_POWER_RET, .core_state = PWRDM_POWER_RET, }, { .mpu_state = PWRDM_POWER_OFF, .core_state = PWRDM_POWER_RET, }, { .mpu_state = PWRDM_POWER_OFF, .core_state = PWRDM_POWER_OFF, }, }; static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; static int _cpuidle_allow_idle(struct powerdomain *pwrdm, struct clockdomain *clkdm) Loading @@ -91,8 +95,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct omap3_idle_statedata *cx = cpuidle_get_statedata(&dev->states_usage[index]); struct omap3_idle_statedata *cx = &omap3_idle_data[index]; u32 mpu_state = cx->mpu_state, core_state = cx->core_state; local_fiq_disable(); Loading Loading @@ -169,14 +172,12 @@ static inline int omap3_enter_idle(struct cpuidle_device *dev, * if it satisfies the enable_off_mode condition. */ static int next_valid_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) struct cpuidle_driver *drv, int index) { struct cpuidle_state_usage *curr_usage = &dev->states_usage[index]; struct cpuidle_state *curr = &drv->states[index]; struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage); struct omap3_idle_statedata *cx = &omap3_idle_data[index]; u32 mpu_deepest_state = PWRDM_POWER_RET; u32 core_deepest_state = PWRDM_POWER_RET; int idx; int next_index = -1; if (enable_off_mode) { Loading @@ -191,44 +192,28 @@ static int next_valid_state(struct cpuidle_device *dev, } /* Check if current state is valid */ if ((cx->valid) && (cx->mpu_state >= mpu_deepest_state) && (cx->core_state >= core_deepest_state)) { if ((cx->mpu_state >= mpu_deepest_state) && (cx->core_state >= core_deepest_state)) return index; } else { int idx = OMAP3_NUM_STATES - 1; /* Reach the current state starting at highest C-state */ for (; idx >= 0; idx--) { if (&drv->states[idx] == curr) { next_index = idx; break; } } /* Should never hit this condition */ WARN_ON(next_index == -1); /* * Drop to next valid state. * Start search from the next (lower) state. */ idx--; for (; idx >= 0; idx--) { cx = cpuidle_get_statedata(&dev->states_usage[idx]); if ((cx->valid) && (cx->mpu_state >= mpu_deepest_state) && for (idx = index - 1; idx >= 0; idx--) { cx = &omap3_idle_data[idx]; if ((cx->mpu_state >= mpu_deepest_state) && (cx->core_state >= core_deepest_state)) { next_index = idx; break; } } /* * C1 is always valid. * So, no need to check for 'next_index == -1' outside * this loop. */ } return next_index; } Loading Loading @@ -273,7 +258,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, * Prevent PER off if CORE is not in retention or off as this * would disable PER wakeups completely. */ cx = cpuidle_get_statedata(&dev->states_usage[index]); cx = &omap3_idle_data[index]; core_next_state = cx->core_state; per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); if ((per_next_state == PWRDM_POWER_OFF) && Loading @@ -298,56 +283,70 @@ select_state: DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) { int i; if (!cpuidle_board_params) return; for (i = 0; i < OMAP3_NUM_STATES; i++) { cpuidle_params_table[i].valid = cpuidle_board_params[i].valid; cpuidle_params_table[i].exit_latency = cpuidle_board_params[i].exit_latency; cpuidle_params_table[i].target_residency = cpuidle_board_params[i].target_residency; } return; } struct cpuidle_driver omap3_idle_driver = { .name = "omap3_idle", .owner = THIS_MODULE, }; /* Helper to fill the C-state common data*/ static inline void _fill_cstate(struct cpuidle_driver *drv, int idx, const char *descr) .states = { { struct cpuidle_state *state = &drv->states[idx]; state->exit_latency = cpuidle_params_table[idx].exit_latency; state->target_residency = cpuidle_params_table[idx].target_residency; state->flags = CPUIDLE_FLAG_TIME_VALID; state->enter = omap3_enter_idle_bm; sprintf(state->name, "C%d", idx + 1); strncpy(state->desc, descr, CPUIDLE_DESC_LEN); } /* Helper to register the driver_data */ static inline struct omap3_idle_statedata *_fill_cstate_usage( struct cpuidle_device *dev, int idx) .enter = omap3_enter_idle, .exit_latency = 2 + 2, .target_residency = 5, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C1", .desc = "MPU ON + CORE ON", }, { struct omap3_idle_statedata *cx = &omap3_idle_data[idx]; struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; cx->valid = cpuidle_params_table[idx].valid; cpuidle_set_statedata(state_usage, cx); return cx; } .enter = omap3_enter_idle_bm, .exit_latency = 10 + 10, .target_residency = 30, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C2", .desc = "MPU ON + CORE ON", }, { .enter = omap3_enter_idle_bm, .exit_latency = 50 + 50, .target_residency = 300, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C3", .desc = "MPU RET + CORE ON", }, { .enter = omap3_enter_idle_bm, .exit_latency = 1500 + 1800, .target_residency = 4000, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C4", .desc = "MPU OFF + CORE ON", }, { .enter = omap3_enter_idle_bm, .exit_latency = 2500 + 7500, .target_residency = 12000, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C5", .desc = "MPU RET + CORE RET", }, { .enter = omap3_enter_idle_bm, .exit_latency = 3000 + 8500, .target_residency = 15000, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C6", .desc = "MPU OFF + CORE RET", }, { .enter = omap3_enter_idle_bm, .exit_latency = 10000 + 30000, .target_residency = 30000, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C7", .desc = "MPU OFF + CORE OFF", }, }, .state_count = ARRAY_SIZE(omap3_idle_data), .safe_state_index = 0, }; /** * omap3_idle_init - Init routine for OMAP3 idle Loading @@ -358,77 +357,20 @@ static inline struct omap3_idle_statedata *_fill_cstate_usage( int __init omap3_idle_init(void) { struct cpuidle_device *dev; struct cpuidle_driver *drv = &omap3_idle_driver; struct omap3_idle_statedata *cx; mpu_pd = pwrdm_lookup("mpu_pwrdm"); core_pd = pwrdm_lookup("core_pwrdm"); per_pd = pwrdm_lookup("per_pwrdm"); cam_pd = pwrdm_lookup("cam_pwrdm"); if (!mpu_pd || !core_pd || !per_pd || !cam_pd) return -ENODEV; drv->safe_state_index = -1; dev = &per_cpu(omap3_idle_dev, smp_processor_id()); /* C1 . MPU WFI + Core active */ _fill_cstate(drv, 0, "MPU ON + CORE ON"); (&drv->states[0])->enter = omap3_enter_idle; drv->safe_state_index = 0; cx = _fill_cstate_usage(dev, 0); cx->valid = 1; /* C1 is always valid */ cx->mpu_state = PWRDM_POWER_ON; cx->core_state = PWRDM_POWER_ON; /* C2 . MPU WFI + Core inactive */ _fill_cstate(drv, 1, "MPU ON + CORE ON"); cx = _fill_cstate_usage(dev, 1); cx->mpu_state = PWRDM_POWER_ON; cx->core_state = PWRDM_POWER_ON; /* C3 . MPU CSWR + Core inactive */ _fill_cstate(drv, 2, "MPU RET + CORE ON"); cx = _fill_cstate_usage(dev, 2); cx->mpu_state = PWRDM_POWER_RET; cx->core_state = PWRDM_POWER_ON; /* C4 . MPU OFF + Core inactive */ _fill_cstate(drv, 3, "MPU OFF + CORE ON"); cx = _fill_cstate_usage(dev, 3); cx->mpu_state = PWRDM_POWER_OFF; cx->core_state = PWRDM_POWER_ON; /* C5 . MPU RET + Core RET */ _fill_cstate(drv, 4, "MPU RET + CORE RET"); cx = _fill_cstate_usage(dev, 4); cx->mpu_state = PWRDM_POWER_RET; cx->core_state = PWRDM_POWER_RET; /* C6 . MPU OFF + Core RET */ _fill_cstate(drv, 5, "MPU OFF + CORE RET"); cx = _fill_cstate_usage(dev, 5); cx->mpu_state = PWRDM_POWER_OFF; cx->core_state = PWRDM_POWER_RET; /* C7 . MPU OFF + Core OFF */ _fill_cstate(drv, 6, "MPU OFF + CORE OFF"); cx = _fill_cstate_usage(dev, 6); /* * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot * enable OFF mode in a stable form for previous revisions. * We disable C7 state as a result. */ if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) { cx->valid = 0; pr_warn("%s: core off state C7 disabled due to i583\n", __func__); } cx->mpu_state = PWRDM_POWER_OFF; cx->core_state = PWRDM_POWER_OFF; drv->state_count = OMAP3_NUM_STATES; cpuidle_register_driver(&omap3_idle_driver); dev->state_count = OMAP3_NUM_STATES; dev = &per_cpu(omap3_idle_dev, smp_processor_id()); dev->cpu = 0; if (cpuidle_register_device(dev)) { printk(KERN_ERR "%s: CPUidle register device failed\n", __func__); Loading arch/arm/mach-omap2/cpuidle44xx.c +52 −74 Original line number Diff line number Diff line Loading @@ -24,26 +24,31 @@ #ifdef CONFIG_CPU_IDLE /* Machine specific information to be recorded in the C-state driver_data */ /* Machine specific information */ struct omap4_idle_statedata { u32 cpu_state; u32 mpu_logic_state; u32 mpu_state; u8 valid; }; static struct cpuidle_params cpuidle_params_table[] = { /* C1 - CPU0 ON + CPU1 ON + MPU ON */ {.exit_latency = 2 + 2 , .target_residency = 5, .valid = 1}, /* C2- CPU0 OFF + CPU1 OFF + MPU CSWR */ {.exit_latency = 328 + 440 , .target_residency = 960, .valid = 1}, /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ {.exit_latency = 460 + 518 , .target_residency = 1100, .valid = 1}, static struct omap4_idle_statedata omap4_idle_data[] = { { .cpu_state = PWRDM_POWER_ON, .mpu_state = PWRDM_POWER_ON, .mpu_logic_state = PWRDM_POWER_RET, }, { .cpu_state = PWRDM_POWER_OFF, .mpu_state = PWRDM_POWER_RET, .mpu_logic_state = PWRDM_POWER_RET, }, { .cpu_state = PWRDM_POWER_OFF, .mpu_state = PWRDM_POWER_RET, .mpu_logic_state = PWRDM_POWER_OFF, }, }; #define OMAP4_NUM_STATES ARRAY_SIZE(cpuidle_params_table) struct omap4_idle_statedata omap4_idle_data[OMAP4_NUM_STATES]; static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; /** Loading @@ -60,8 +65,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct omap4_idle_statedata *cx = cpuidle_get_statedata(&dev->states_usage[index]); struct omap4_idle_statedata *cx = &omap4_idle_data[index]; u32 cpu1_state; int cpu_id = smp_processor_id(); Loading @@ -78,7 +82,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev, cpu1_state = pwrdm_read_pwrst(cpu1_pd); if (cpu1_state != PWRDM_POWER_OFF) { index = drv->safe_state_index; cx = cpuidle_get_statedata(&dev->states_usage[index]); cx = &omap4_idle_data[index]; } if (index > 0) Loading Loading @@ -133,35 +137,38 @@ struct cpuidle_driver omap4_idle_driver = { .name = "omap4_idle", .owner = THIS_MODULE, .en_core_tk_irqen = 1, }; static inline void _fill_cstate(struct cpuidle_driver *drv, int idx, const char *descr) .states = { { struct cpuidle_state *state = &drv->states[idx]; state->exit_latency = cpuidle_params_table[idx].exit_latency; state->target_residency = cpuidle_params_table[idx].target_residency; state->flags = CPUIDLE_FLAG_TIME_VALID; state->enter = omap4_enter_idle; sprintf(state->name, "C%d", idx + 1); strncpy(state->desc, descr, CPUIDLE_DESC_LEN); } static inline struct omap4_idle_statedata *_fill_cstate_usage( struct cpuidle_device *dev, int idx) /* C1 - CPU0 ON + CPU1 ON + MPU ON */ .exit_latency = 2 + 2, .target_residency = 5, .flags = CPUIDLE_FLAG_TIME_VALID, .enter = omap4_enter_idle, .name = "C1", .desc = "MPUSS ON" }, { struct omap4_idle_statedata *cx = &omap4_idle_data[idx]; struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; cx->valid = cpuidle_params_table[idx].valid; cpuidle_set_statedata(state_usage, cx); return cx; } /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ .exit_latency = 328 + 440, .target_residency = 960, .flags = CPUIDLE_FLAG_TIME_VALID, .enter = omap4_enter_idle, .name = "C2", .desc = "MPUSS CSWR", }, { /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ .exit_latency = 460 + 518, .target_residency = 1100, .flags = CPUIDLE_FLAG_TIME_VALID, .enter = omap4_enter_idle, .name = "C3", .desc = "MPUSS OSWR", }, }, .state_count = ARRAY_SIZE(omap4_idle_data), .safe_state_index = 0, }; /** * omap4_idle_init - Init routine for OMAP4 idle Loading @@ -171,9 +178,7 @@ static inline struct omap4_idle_statedata *_fill_cstate_usage( */ int __init omap4_idle_init(void) { struct omap4_idle_statedata *cx; struct cpuidle_device *dev; struct cpuidle_driver *drv = &omap4_idle_driver; unsigned int cpu_id = 0; mpu_pd = pwrdm_lookup("mpu_pwrdm"); Loading @@ -182,38 +187,11 @@ int __init omap4_idle_init(void) if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) return -ENODEV; drv->safe_state_index = -1; dev = &per_cpu(omap4_idle_dev, cpu_id); dev->cpu = cpu_id; /* C1 - CPU0 ON + CPU1 ON + MPU ON */ _fill_cstate(drv, 0, "MPUSS ON"); drv->safe_state_index = 0; cx = _fill_cstate_usage(dev, 0); cx->valid = 1; /* C1 is always valid */ cx->cpu_state = PWRDM_POWER_ON; cx->mpu_state = PWRDM_POWER_ON; cx->mpu_logic_state = PWRDM_POWER_RET; /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ _fill_cstate(drv, 1, "MPUSS CSWR"); cx = _fill_cstate_usage(dev, 1); cx->cpu_state = PWRDM_POWER_OFF; cx->mpu_state = PWRDM_POWER_RET; cx->mpu_logic_state = PWRDM_POWER_RET; /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ _fill_cstate(drv, 2, "MPUSS OSWR"); cx = _fill_cstate_usage(dev, 2); cx->cpu_state = PWRDM_POWER_OFF; cx->mpu_state = PWRDM_POWER_RET; cx->mpu_logic_state = PWRDM_POWER_OFF; drv->state_count = OMAP4_NUM_STATES; cpuidle_register_driver(&omap4_idle_driver); dev->state_count = OMAP4_NUM_STATES; if (cpuidle_register_device(dev)) { pr_err("%s: CPUidle register device failed\n", __func__); return -EIO; Loading arch/arm/mach-omap2/pm.h +0 −21 Original line number Diff line number Diff line Loading @@ -38,27 +38,6 @@ static inline int omap4_opp_init(void) } #endif /* * cpuidle mach specific parameters * * The board code can override the default C-states definition using * omap3_pm_init_cpuidle */ struct cpuidle_params { u32 exit_latency; /* exit_latency = sleep + wake-up latencies */ u32 target_residency; u8 valid; /* validates the C-state */ }; #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 Loading
arch/arm/mach-omap2/board-rx51.c +18 −20 Original line number Diff line number Diff line Loading @@ -59,25 +59,24 @@ static struct platform_device leds_gpio = { }; /* * cpuidle C-states definition override from the default values. * The 'exit_latency' field is the sum of sleep and wake-up latencies. * cpuidle C-states definition for rx51. * * The 'exit_latency' field is the sum of sleep * and wake-up latencies. --------------------------------------------- | state | exit_latency | target_residency | --------------------------------------------- | C1 | 110 + 162 | 5 | | C2 | 106 + 180 | 309 | | C3 | 107 + 410 | 46057 | | C4 | 121 + 3374 | 46057 | | C5 | 855 + 1146 | 46057 | | C6 | 7580 + 4134 | 484329 | | C7 | 7505 + 15274 | 484329 | --------------------------------------------- */ static struct cpuidle_params rx51_cpuidle_params[] = { /* C1 */ {110 + 162, 5 , 1}, /* C2 */ {106 + 180, 309, 1}, /* C3 */ {107 + 410, 46057, 0}, /* C4 */ {121 + 3374, 46057, 0}, /* C5 */ {855 + 1146, 46057, 1}, /* C6 */ {7580 + 4134, 484329, 0}, /* C7 */ {7505 + 15274, 484329, 1}, }; extern void __init rx51_peripherals_init(void); Loading @@ -98,7 +97,6 @@ static void __init rx51_init(void) struct omap_sdrc_params *sdrc_params; omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3_pm_init_cpuidle(rx51_cpuidle_params); omap_serial_init(); sdrc_params = nokia_get_sdram_timings(); Loading
arch/arm/mach-omap2/cpuidle34xx.c +120 −178 Original line number Diff line number Diff line Loading @@ -38,40 +38,44 @@ #ifdef CONFIG_CPU_IDLE /* * 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 */ {2 + 2, 5, 1}, /* C2 */ {10 + 10, 30, 1}, /* C3 */ {50 + 50, 300, 1}, /* C4 */ {1500 + 1800, 4000, 1}, /* C5 */ {2500 + 7500, 12000, 1}, /* C6 */ {3000 + 8500, 15000, 1}, /* C7 */ {10000 + 30000, 300000, 1}, }; #define OMAP3_NUM_STATES ARRAY_SIZE(cpuidle_params_table) /* Mach specific information to be recorded in the C-state driver_data */ struct omap3_idle_statedata { u32 mpu_state; u32 core_state; u8 valid; }; struct omap3_idle_statedata omap3_idle_data[OMAP3_NUM_STATES]; struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; static struct omap3_idle_statedata omap3_idle_data[] = { { .mpu_state = PWRDM_POWER_ON, .core_state = PWRDM_POWER_ON, }, { .mpu_state = PWRDM_POWER_ON, .core_state = PWRDM_POWER_ON, }, { .mpu_state = PWRDM_POWER_RET, .core_state = PWRDM_POWER_ON, }, { .mpu_state = PWRDM_POWER_OFF, .core_state = PWRDM_POWER_ON, }, { .mpu_state = PWRDM_POWER_RET, .core_state = PWRDM_POWER_RET, }, { .mpu_state = PWRDM_POWER_OFF, .core_state = PWRDM_POWER_RET, }, { .mpu_state = PWRDM_POWER_OFF, .core_state = PWRDM_POWER_OFF, }, }; static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; static int _cpuidle_allow_idle(struct powerdomain *pwrdm, struct clockdomain *clkdm) Loading @@ -91,8 +95,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct omap3_idle_statedata *cx = cpuidle_get_statedata(&dev->states_usage[index]); struct omap3_idle_statedata *cx = &omap3_idle_data[index]; u32 mpu_state = cx->mpu_state, core_state = cx->core_state; local_fiq_disable(); Loading Loading @@ -169,14 +172,12 @@ static inline int omap3_enter_idle(struct cpuidle_device *dev, * if it satisfies the enable_off_mode condition. */ static int next_valid_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) struct cpuidle_driver *drv, int index) { struct cpuidle_state_usage *curr_usage = &dev->states_usage[index]; struct cpuidle_state *curr = &drv->states[index]; struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage); struct omap3_idle_statedata *cx = &omap3_idle_data[index]; u32 mpu_deepest_state = PWRDM_POWER_RET; u32 core_deepest_state = PWRDM_POWER_RET; int idx; int next_index = -1; if (enable_off_mode) { Loading @@ -191,44 +192,28 @@ static int next_valid_state(struct cpuidle_device *dev, } /* Check if current state is valid */ if ((cx->valid) && (cx->mpu_state >= mpu_deepest_state) && (cx->core_state >= core_deepest_state)) { if ((cx->mpu_state >= mpu_deepest_state) && (cx->core_state >= core_deepest_state)) return index; } else { int idx = OMAP3_NUM_STATES - 1; /* Reach the current state starting at highest C-state */ for (; idx >= 0; idx--) { if (&drv->states[idx] == curr) { next_index = idx; break; } } /* Should never hit this condition */ WARN_ON(next_index == -1); /* * Drop to next valid state. * Start search from the next (lower) state. */ idx--; for (; idx >= 0; idx--) { cx = cpuidle_get_statedata(&dev->states_usage[idx]); if ((cx->valid) && (cx->mpu_state >= mpu_deepest_state) && for (idx = index - 1; idx >= 0; idx--) { cx = &omap3_idle_data[idx]; if ((cx->mpu_state >= mpu_deepest_state) && (cx->core_state >= core_deepest_state)) { next_index = idx; break; } } /* * C1 is always valid. * So, no need to check for 'next_index == -1' outside * this loop. */ } return next_index; } Loading Loading @@ -273,7 +258,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, * Prevent PER off if CORE is not in retention or off as this * would disable PER wakeups completely. */ cx = cpuidle_get_statedata(&dev->states_usage[index]); cx = &omap3_idle_data[index]; core_next_state = cx->core_state; per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); if ((per_next_state == PWRDM_POWER_OFF) && Loading @@ -298,56 +283,70 @@ select_state: DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) { int i; if (!cpuidle_board_params) return; for (i = 0; i < OMAP3_NUM_STATES; i++) { cpuidle_params_table[i].valid = cpuidle_board_params[i].valid; cpuidle_params_table[i].exit_latency = cpuidle_board_params[i].exit_latency; cpuidle_params_table[i].target_residency = cpuidle_board_params[i].target_residency; } return; } struct cpuidle_driver omap3_idle_driver = { .name = "omap3_idle", .owner = THIS_MODULE, }; /* Helper to fill the C-state common data*/ static inline void _fill_cstate(struct cpuidle_driver *drv, int idx, const char *descr) .states = { { struct cpuidle_state *state = &drv->states[idx]; state->exit_latency = cpuidle_params_table[idx].exit_latency; state->target_residency = cpuidle_params_table[idx].target_residency; state->flags = CPUIDLE_FLAG_TIME_VALID; state->enter = omap3_enter_idle_bm; sprintf(state->name, "C%d", idx + 1); strncpy(state->desc, descr, CPUIDLE_DESC_LEN); } /* Helper to register the driver_data */ static inline struct omap3_idle_statedata *_fill_cstate_usage( struct cpuidle_device *dev, int idx) .enter = omap3_enter_idle, .exit_latency = 2 + 2, .target_residency = 5, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C1", .desc = "MPU ON + CORE ON", }, { struct omap3_idle_statedata *cx = &omap3_idle_data[idx]; struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; cx->valid = cpuidle_params_table[idx].valid; cpuidle_set_statedata(state_usage, cx); return cx; } .enter = omap3_enter_idle_bm, .exit_latency = 10 + 10, .target_residency = 30, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C2", .desc = "MPU ON + CORE ON", }, { .enter = omap3_enter_idle_bm, .exit_latency = 50 + 50, .target_residency = 300, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C3", .desc = "MPU RET + CORE ON", }, { .enter = omap3_enter_idle_bm, .exit_latency = 1500 + 1800, .target_residency = 4000, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C4", .desc = "MPU OFF + CORE ON", }, { .enter = omap3_enter_idle_bm, .exit_latency = 2500 + 7500, .target_residency = 12000, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C5", .desc = "MPU RET + CORE RET", }, { .enter = omap3_enter_idle_bm, .exit_latency = 3000 + 8500, .target_residency = 15000, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C6", .desc = "MPU OFF + CORE RET", }, { .enter = omap3_enter_idle_bm, .exit_latency = 10000 + 30000, .target_residency = 30000, .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C7", .desc = "MPU OFF + CORE OFF", }, }, .state_count = ARRAY_SIZE(omap3_idle_data), .safe_state_index = 0, }; /** * omap3_idle_init - Init routine for OMAP3 idle Loading @@ -358,77 +357,20 @@ static inline struct omap3_idle_statedata *_fill_cstate_usage( int __init omap3_idle_init(void) { struct cpuidle_device *dev; struct cpuidle_driver *drv = &omap3_idle_driver; struct omap3_idle_statedata *cx; mpu_pd = pwrdm_lookup("mpu_pwrdm"); core_pd = pwrdm_lookup("core_pwrdm"); per_pd = pwrdm_lookup("per_pwrdm"); cam_pd = pwrdm_lookup("cam_pwrdm"); if (!mpu_pd || !core_pd || !per_pd || !cam_pd) return -ENODEV; drv->safe_state_index = -1; dev = &per_cpu(omap3_idle_dev, smp_processor_id()); /* C1 . MPU WFI + Core active */ _fill_cstate(drv, 0, "MPU ON + CORE ON"); (&drv->states[0])->enter = omap3_enter_idle; drv->safe_state_index = 0; cx = _fill_cstate_usage(dev, 0); cx->valid = 1; /* C1 is always valid */ cx->mpu_state = PWRDM_POWER_ON; cx->core_state = PWRDM_POWER_ON; /* C2 . MPU WFI + Core inactive */ _fill_cstate(drv, 1, "MPU ON + CORE ON"); cx = _fill_cstate_usage(dev, 1); cx->mpu_state = PWRDM_POWER_ON; cx->core_state = PWRDM_POWER_ON; /* C3 . MPU CSWR + Core inactive */ _fill_cstate(drv, 2, "MPU RET + CORE ON"); cx = _fill_cstate_usage(dev, 2); cx->mpu_state = PWRDM_POWER_RET; cx->core_state = PWRDM_POWER_ON; /* C4 . MPU OFF + Core inactive */ _fill_cstate(drv, 3, "MPU OFF + CORE ON"); cx = _fill_cstate_usage(dev, 3); cx->mpu_state = PWRDM_POWER_OFF; cx->core_state = PWRDM_POWER_ON; /* C5 . MPU RET + Core RET */ _fill_cstate(drv, 4, "MPU RET + CORE RET"); cx = _fill_cstate_usage(dev, 4); cx->mpu_state = PWRDM_POWER_RET; cx->core_state = PWRDM_POWER_RET; /* C6 . MPU OFF + Core RET */ _fill_cstate(drv, 5, "MPU OFF + CORE RET"); cx = _fill_cstate_usage(dev, 5); cx->mpu_state = PWRDM_POWER_OFF; cx->core_state = PWRDM_POWER_RET; /* C7 . MPU OFF + Core OFF */ _fill_cstate(drv, 6, "MPU OFF + CORE OFF"); cx = _fill_cstate_usage(dev, 6); /* * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot * enable OFF mode in a stable form for previous revisions. * We disable C7 state as a result. */ if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) { cx->valid = 0; pr_warn("%s: core off state C7 disabled due to i583\n", __func__); } cx->mpu_state = PWRDM_POWER_OFF; cx->core_state = PWRDM_POWER_OFF; drv->state_count = OMAP3_NUM_STATES; cpuidle_register_driver(&omap3_idle_driver); dev->state_count = OMAP3_NUM_STATES; dev = &per_cpu(omap3_idle_dev, smp_processor_id()); dev->cpu = 0; if (cpuidle_register_device(dev)) { printk(KERN_ERR "%s: CPUidle register device failed\n", __func__); Loading
arch/arm/mach-omap2/cpuidle44xx.c +52 −74 Original line number Diff line number Diff line Loading @@ -24,26 +24,31 @@ #ifdef CONFIG_CPU_IDLE /* Machine specific information to be recorded in the C-state driver_data */ /* Machine specific information */ struct omap4_idle_statedata { u32 cpu_state; u32 mpu_logic_state; u32 mpu_state; u8 valid; }; static struct cpuidle_params cpuidle_params_table[] = { /* C1 - CPU0 ON + CPU1 ON + MPU ON */ {.exit_latency = 2 + 2 , .target_residency = 5, .valid = 1}, /* C2- CPU0 OFF + CPU1 OFF + MPU CSWR */ {.exit_latency = 328 + 440 , .target_residency = 960, .valid = 1}, /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ {.exit_latency = 460 + 518 , .target_residency = 1100, .valid = 1}, static struct omap4_idle_statedata omap4_idle_data[] = { { .cpu_state = PWRDM_POWER_ON, .mpu_state = PWRDM_POWER_ON, .mpu_logic_state = PWRDM_POWER_RET, }, { .cpu_state = PWRDM_POWER_OFF, .mpu_state = PWRDM_POWER_RET, .mpu_logic_state = PWRDM_POWER_RET, }, { .cpu_state = PWRDM_POWER_OFF, .mpu_state = PWRDM_POWER_RET, .mpu_logic_state = PWRDM_POWER_OFF, }, }; #define OMAP4_NUM_STATES ARRAY_SIZE(cpuidle_params_table) struct omap4_idle_statedata omap4_idle_data[OMAP4_NUM_STATES]; static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; /** Loading @@ -60,8 +65,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct omap4_idle_statedata *cx = cpuidle_get_statedata(&dev->states_usage[index]); struct omap4_idle_statedata *cx = &omap4_idle_data[index]; u32 cpu1_state; int cpu_id = smp_processor_id(); Loading @@ -78,7 +82,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev, cpu1_state = pwrdm_read_pwrst(cpu1_pd); if (cpu1_state != PWRDM_POWER_OFF) { index = drv->safe_state_index; cx = cpuidle_get_statedata(&dev->states_usage[index]); cx = &omap4_idle_data[index]; } if (index > 0) Loading Loading @@ -133,35 +137,38 @@ struct cpuidle_driver omap4_idle_driver = { .name = "omap4_idle", .owner = THIS_MODULE, .en_core_tk_irqen = 1, }; static inline void _fill_cstate(struct cpuidle_driver *drv, int idx, const char *descr) .states = { { struct cpuidle_state *state = &drv->states[idx]; state->exit_latency = cpuidle_params_table[idx].exit_latency; state->target_residency = cpuidle_params_table[idx].target_residency; state->flags = CPUIDLE_FLAG_TIME_VALID; state->enter = omap4_enter_idle; sprintf(state->name, "C%d", idx + 1); strncpy(state->desc, descr, CPUIDLE_DESC_LEN); } static inline struct omap4_idle_statedata *_fill_cstate_usage( struct cpuidle_device *dev, int idx) /* C1 - CPU0 ON + CPU1 ON + MPU ON */ .exit_latency = 2 + 2, .target_residency = 5, .flags = CPUIDLE_FLAG_TIME_VALID, .enter = omap4_enter_idle, .name = "C1", .desc = "MPUSS ON" }, { struct omap4_idle_statedata *cx = &omap4_idle_data[idx]; struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; cx->valid = cpuidle_params_table[idx].valid; cpuidle_set_statedata(state_usage, cx); return cx; } /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ .exit_latency = 328 + 440, .target_residency = 960, .flags = CPUIDLE_FLAG_TIME_VALID, .enter = omap4_enter_idle, .name = "C2", .desc = "MPUSS CSWR", }, { /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ .exit_latency = 460 + 518, .target_residency = 1100, .flags = CPUIDLE_FLAG_TIME_VALID, .enter = omap4_enter_idle, .name = "C3", .desc = "MPUSS OSWR", }, }, .state_count = ARRAY_SIZE(omap4_idle_data), .safe_state_index = 0, }; /** * omap4_idle_init - Init routine for OMAP4 idle Loading @@ -171,9 +178,7 @@ static inline struct omap4_idle_statedata *_fill_cstate_usage( */ int __init omap4_idle_init(void) { struct omap4_idle_statedata *cx; struct cpuidle_device *dev; struct cpuidle_driver *drv = &omap4_idle_driver; unsigned int cpu_id = 0; mpu_pd = pwrdm_lookup("mpu_pwrdm"); Loading @@ -182,38 +187,11 @@ int __init omap4_idle_init(void) if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) return -ENODEV; drv->safe_state_index = -1; dev = &per_cpu(omap4_idle_dev, cpu_id); dev->cpu = cpu_id; /* C1 - CPU0 ON + CPU1 ON + MPU ON */ _fill_cstate(drv, 0, "MPUSS ON"); drv->safe_state_index = 0; cx = _fill_cstate_usage(dev, 0); cx->valid = 1; /* C1 is always valid */ cx->cpu_state = PWRDM_POWER_ON; cx->mpu_state = PWRDM_POWER_ON; cx->mpu_logic_state = PWRDM_POWER_RET; /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ _fill_cstate(drv, 1, "MPUSS CSWR"); cx = _fill_cstate_usage(dev, 1); cx->cpu_state = PWRDM_POWER_OFF; cx->mpu_state = PWRDM_POWER_RET; cx->mpu_logic_state = PWRDM_POWER_RET; /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ _fill_cstate(drv, 2, "MPUSS OSWR"); cx = _fill_cstate_usage(dev, 2); cx->cpu_state = PWRDM_POWER_OFF; cx->mpu_state = PWRDM_POWER_RET; cx->mpu_logic_state = PWRDM_POWER_OFF; drv->state_count = OMAP4_NUM_STATES; cpuidle_register_driver(&omap4_idle_driver); dev->state_count = OMAP4_NUM_STATES; if (cpuidle_register_device(dev)) { pr_err("%s: CPUidle register device failed\n", __func__); return -EIO; Loading
arch/arm/mach-omap2/pm.h +0 −21 Original line number Diff line number Diff line Loading @@ -38,27 +38,6 @@ static inline int omap4_opp_init(void) } #endif /* * cpuidle mach specific parameters * * The board code can override the default C-states definition using * omap3_pm_init_cpuidle */ struct cpuidle_params { u32 exit_latency; /* exit_latency = sleep + wake-up latencies */ u32 target_residency; u8 valid; /* validates the C-state */ }; #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