diff options
Diffstat (limited to 'arch/arm/mach-omap2/pm34xx.c')
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 86 |
1 files changed, 37 insertions, 49 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index c155c9d1c82c..7255d9bce868 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/console.h> | 31 | #include <linux/console.h> |
32 | #include <trace/events/power.h> | 32 | #include <trace/events/power.h> |
33 | 33 | ||
34 | #include <asm/suspend.h> | ||
35 | |||
34 | #include <plat/sram.h> | 36 | #include <plat/sram.h> |
35 | #include "clockdomain.h" | 37 | #include "clockdomain.h" |
36 | #include "powerdomain.h" | 38 | #include "powerdomain.h" |
@@ -40,8 +42,6 @@ | |||
40 | #include <plat/gpmc.h> | 42 | #include <plat/gpmc.h> |
41 | #include <plat/dma.h> | 43 | #include <plat/dma.h> |
42 | 44 | ||
43 | #include <asm/tlbflush.h> | ||
44 | |||
45 | #include "cm2xxx_3xxx.h" | 45 | #include "cm2xxx_3xxx.h" |
46 | #include "cm-regbits-34xx.h" | 46 | #include "cm-regbits-34xx.h" |
47 | #include "prm-regbits-34xx.h" | 47 | #include "prm-regbits-34xx.h" |
@@ -64,11 +64,6 @@ static inline bool is_suspending(void) | |||
64 | } | 64 | } |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | /* Scratchpad offsets */ | ||
68 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 | ||
69 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 | ||
70 | #define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8 | ||
71 | |||
72 | /* pm34xx errata defined in pm.h */ | 67 | /* pm34xx errata defined in pm.h */ |
73 | u16 pm34xx_errata; | 68 | u16 pm34xx_errata; |
74 | 69 | ||
@@ -83,9 +78,8 @@ struct power_state { | |||
83 | 78 | ||
84 | static LIST_HEAD(pwrst_list); | 79 | static LIST_HEAD(pwrst_list); |
85 | 80 | ||
86 | static void (*_omap_sram_idle)(u32 *addr, int save_state); | ||
87 | |||
88 | static int (*_omap_save_secure_sram)(u32 *addr); | 81 | static int (*_omap_save_secure_sram)(u32 *addr); |
82 | void (*omap3_do_wfi_sram)(void); | ||
89 | 83 | ||
90 | static struct powerdomain *mpu_pwrdm, *neon_pwrdm; | 84 | static struct powerdomain *mpu_pwrdm, *neon_pwrdm; |
91 | static struct powerdomain *core_pwrdm, *per_pwrdm; | 85 | static struct powerdomain *core_pwrdm, *per_pwrdm; |
@@ -312,28 +306,25 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) | |||
312 | return IRQ_HANDLED; | 306 | return IRQ_HANDLED; |
313 | } | 307 | } |
314 | 308 | ||
315 | /* Function to restore the table entry that was modified for enabling MMU */ | 309 | static void omap34xx_save_context(u32 *save) |
316 | static void restore_table_entry(void) | ||
317 | { | 310 | { |
318 | void __iomem *scratchpad_address; | 311 | u32 val; |
319 | u32 previous_value, control_reg_value; | ||
320 | u32 *address; | ||
321 | 312 | ||
322 | scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD); | 313 | /* Read Auxiliary Control Register */ |
314 | asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (val)); | ||
315 | *save++ = 1; | ||
316 | *save++ = val; | ||
323 | 317 | ||
324 | /* Get address of entry that was modified */ | 318 | /* Read L2 AUX ctrl register */ |
325 | address = (u32 *)__raw_readl(scratchpad_address + | 319 | asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (val)); |
326 | OMAP343X_TABLE_ADDRESS_OFFSET); | 320 | *save++ = 1; |
327 | /* Get the previous value which needs to be restored */ | 321 | *save++ = val; |
328 | previous_value = __raw_readl(scratchpad_address + | 322 | } |
329 | OMAP343X_TABLE_VALUE_OFFSET); | 323 | |
330 | address = __va(address); | 324 | static int omap34xx_do_sram_idle(unsigned long save_state) |
331 | *address = previous_value; | 325 | { |
332 | flush_tlb_all(); | 326 | omap34xx_cpu_suspend(save_state); |
333 | control_reg_value = __raw_readl(scratchpad_address | 327 | return 0; |
334 | + OMAP343X_CONTROL_REG_VALUE_OFFSET); | ||
335 | /* This will enable caches and prediction */ | ||
336 | set_cr(control_reg_value); | ||
337 | } | 328 | } |
338 | 329 | ||
339 | void omap_sram_idle(void) | 330 | void omap_sram_idle(void) |
@@ -352,9 +343,6 @@ void omap_sram_idle(void) | |||
352 | int core_prev_state, per_prev_state; | 343 | int core_prev_state, per_prev_state; |
353 | u32 sdrc_pwr = 0; | 344 | u32 sdrc_pwr = 0; |
354 | 345 | ||
355 | if (!_omap_sram_idle) | ||
356 | return; | ||
357 | |||
358 | pwrdm_clear_all_prev_pwrst(mpu_pwrdm); | 346 | pwrdm_clear_all_prev_pwrst(mpu_pwrdm); |
359 | pwrdm_clear_all_prev_pwrst(neon_pwrdm); | 347 | pwrdm_clear_all_prev_pwrst(neon_pwrdm); |
360 | pwrdm_clear_all_prev_pwrst(core_pwrdm); | 348 | pwrdm_clear_all_prev_pwrst(core_pwrdm); |
@@ -432,12 +420,16 @@ void omap_sram_idle(void) | |||
432 | sdrc_pwr = sdrc_read_reg(SDRC_POWER); | 420 | sdrc_pwr = sdrc_read_reg(SDRC_POWER); |
433 | 421 | ||
434 | /* | 422 | /* |
435 | * omap3_arm_context is the location where ARM registers | 423 | * omap3_arm_context is the location where some ARM context |
436 | * get saved. The restore path then reads from this | 424 | * get saved. The rest is placed on the stack, and restored |
437 | * location and restores them back. | 425 | * from there before resuming. |
438 | */ | 426 | */ |
439 | _omap_sram_idle(omap3_arm_context, save_state); | 427 | if (save_state) |
440 | cpu_init(); | 428 | omap34xx_save_context(omap3_arm_context); |
429 | if (save_state == 1 || save_state == 3) | ||
430 | cpu_suspend(save_state, omap34xx_do_sram_idle); | ||
431 | else | ||
432 | omap34xx_do_sram_idle(save_state); | ||
441 | 433 | ||
442 | /* Restore normal SDRC POWER settings */ | 434 | /* Restore normal SDRC POWER settings */ |
443 | if (omap_rev() >= OMAP3430_REV_ES3_0 && | 435 | if (omap_rev() >= OMAP3430_REV_ES3_0 && |
@@ -445,10 +437,6 @@ void omap_sram_idle(void) | |||
445 | core_next_state == PWRDM_POWER_OFF) | 437 | core_next_state == PWRDM_POWER_OFF) |
446 | sdrc_write_reg(sdrc_pwr, SDRC_POWER); | 438 | sdrc_write_reg(sdrc_pwr, SDRC_POWER); |
447 | 439 | ||
448 | /* Restore table entry modified during MMU restoration */ | ||
449 | if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF) | ||
450 | restore_table_entry(); | ||
451 | |||
452 | /* CORE */ | 440 | /* CORE */ |
453 | if (core_next_state < PWRDM_POWER_ON) { | 441 | if (core_next_state < PWRDM_POWER_ON) { |
454 | core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); | 442 | core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); |
@@ -497,8 +485,6 @@ console_still_active: | |||
497 | 485 | ||
498 | int omap3_can_sleep(void) | 486 | int omap3_can_sleep(void) |
499 | { | 487 | { |
500 | if (!sleep_while_idle) | ||
501 | return 0; | ||
502 | if (!omap_uart_can_sleep()) | 488 | if (!omap_uart_can_sleep()) |
503 | return 0; | 489 | return 0; |
504 | return 1; | 490 | return 1; |
@@ -534,10 +520,6 @@ static int omap3_pm_suspend(void) | |||
534 | struct power_state *pwrst; | 520 | struct power_state *pwrst; |
535 | int state, ret = 0; | 521 | int state, ret = 0; |
536 | 522 | ||
537 | if (wakeup_timer_seconds || wakeup_timer_milliseconds) | ||
538 | omap2_pm_wakeup_on_timer(wakeup_timer_seconds, | ||
539 | wakeup_timer_milliseconds); | ||
540 | |||
541 | /* Read current next_pwrsts */ | 523 | /* Read current next_pwrsts */ |
542 | list_for_each_entry(pwrst, &pwrst_list, node) | 524 | list_for_each_entry(pwrst, &pwrst_list, node) |
543 | pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); | 525 | pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); |
@@ -852,10 +834,17 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) | |||
852 | return 0; | 834 | return 0; |
853 | } | 835 | } |
854 | 836 | ||
837 | /* | ||
838 | * Push functions to SRAM | ||
839 | * | ||
840 | * The minimum set of functions is pushed to SRAM for execution: | ||
841 | * - omap3_do_wfi for erratum i581 WA, | ||
842 | * - save_secure_ram_context for security extensions. | ||
843 | */ | ||
855 | void omap_push_sram_idle(void) | 844 | void omap_push_sram_idle(void) |
856 | { | 845 | { |
857 | _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, | 846 | omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz); |
858 | omap34xx_cpu_suspend_sz); | 847 | |
859 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) | 848 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) |
860 | _omap_save_secure_sram = omap_sram_push(save_secure_ram_context, | 849 | _omap_save_secure_sram = omap_sram_push(save_secure_ram_context, |
861 | save_secure_ram_context_sz); | 850 | save_secure_ram_context_sz); |
@@ -920,7 +909,6 @@ static int __init omap3_pm_init(void) | |||
920 | per_clkdm = clkdm_lookup("per_clkdm"); | 909 | per_clkdm = clkdm_lookup("per_clkdm"); |
921 | core_clkdm = clkdm_lookup("core_clkdm"); | 910 | core_clkdm = clkdm_lookup("core_clkdm"); |
922 | 911 | ||
923 | omap_push_sram_idle(); | ||
924 | #ifdef CONFIG_SUSPEND | 912 | #ifdef CONFIG_SUSPEND |
925 | suspend_set_ops(&omap_pm_ops); | 913 | suspend_set_ops(&omap_pm_ops); |
926 | #endif /* CONFIG_SUSPEND */ | 914 | #endif /* CONFIG_SUSPEND */ |