aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm34xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/pm34xx.c')
-rw-r--r--arch/arm/mach-omap2/pm34xx.c86
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 */
73u16 pm34xx_errata; 68u16 pm34xx_errata;
74 69
@@ -83,9 +78,8 @@ struct power_state {
83 78
84static LIST_HEAD(pwrst_list); 79static LIST_HEAD(pwrst_list);
85 80
86static void (*_omap_sram_idle)(u32 *addr, int save_state);
87
88static int (*_omap_save_secure_sram)(u32 *addr); 81static int (*_omap_save_secure_sram)(u32 *addr);
82void (*omap3_do_wfi_sram)(void);
89 83
90static struct powerdomain *mpu_pwrdm, *neon_pwrdm; 84static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
91static struct powerdomain *core_pwrdm, *per_pwrdm; 85static 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 */ 309static void omap34xx_save_context(u32 *save)
316static 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); 324static 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
339void omap_sram_idle(void) 330void 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
498int omap3_can_sleep(void) 486int 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 */
855void omap_push_sram_idle(void) 844void 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 */