diff options
Diffstat (limited to 'arch/arm/mach-omap2/pm34xx.c')
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 66 |
1 files changed, 48 insertions, 18 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 648b8c50d024..c45b4fa1deeb 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -68,6 +68,9 @@ static inline bool is_suspending(void) | |||
68 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 | 68 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 |
69 | #define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8 | 69 | #define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8 |
70 | 70 | ||
71 | /* pm34xx errata defined in pm.h */ | ||
72 | u16 pm34xx_errata; | ||
73 | |||
71 | struct power_state { | 74 | struct power_state { |
72 | struct powerdomain *pwrdm; | 75 | struct powerdomain *pwrdm; |
73 | u32 next_state; | 76 | u32 next_state; |
@@ -143,7 +146,7 @@ static void omap3_core_save_context(void) | |||
143 | 146 | ||
144 | /* | 147 | /* |
145 | * Force write last pad into memory, as this can fail in some | 148 | * Force write last pad into memory, as this can fail in some |
146 | * cases according to erratas 1.157, 1.185 | 149 | * cases according to errata 1.157, 1.185 |
147 | */ | 150 | */ |
148 | omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14), | 151 | omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14), |
149 | OMAP343X_CONTROL_MEM_WKUP + 0x2a0); | 152 | OMAP343X_CONTROL_MEM_WKUP + 0x2a0); |
@@ -430,7 +433,7 @@ void omap_sram_idle(void) | |||
430 | /* | 433 | /* |
431 | * On EMU/HS devices ROM code restores a SRDC value | 434 | * On EMU/HS devices ROM code restores a SRDC value |
432 | * from scratchpad which has automatic self refresh on timeout | 435 | * from scratchpad which has automatic self refresh on timeout |
433 | * of AUTO_CNT = 1 enabled. This takes care of errata 1.142. | 436 | * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443. |
434 | * Hence store/restore the SDRC_POWER register here. | 437 | * Hence store/restore the SDRC_POWER register here. |
435 | */ | 438 | */ |
436 | if (omap_rev() >= OMAP3430_REV_ES3_0 && | 439 | if (omap_rev() >= OMAP3430_REV_ES3_0 && |
@@ -529,12 +532,6 @@ out: | |||
529 | } | 532 | } |
530 | 533 | ||
531 | #ifdef CONFIG_SUSPEND | 534 | #ifdef CONFIG_SUSPEND |
532 | static int omap3_pm_prepare(void) | ||
533 | { | ||
534 | disable_hlt(); | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int omap3_pm_suspend(void) | 535 | static int omap3_pm_suspend(void) |
539 | { | 536 | { |
540 | struct power_state *pwrst; | 537 | struct power_state *pwrst; |
@@ -597,14 +594,10 @@ static int omap3_pm_enter(suspend_state_t unused) | |||
597 | return ret; | 594 | return ret; |
598 | } | 595 | } |
599 | 596 | ||
600 | static void omap3_pm_finish(void) | ||
601 | { | ||
602 | enable_hlt(); | ||
603 | } | ||
604 | |||
605 | /* Hooks to enable / disable UART interrupts during suspend */ | 597 | /* Hooks to enable / disable UART interrupts during suspend */ |
606 | static int omap3_pm_begin(suspend_state_t state) | 598 | static int omap3_pm_begin(suspend_state_t state) |
607 | { | 599 | { |
600 | disable_hlt(); | ||
608 | suspend_state = state; | 601 | suspend_state = state; |
609 | omap_uart_enable_irqs(0); | 602 | omap_uart_enable_irqs(0); |
610 | return 0; | 603 | return 0; |
@@ -614,15 +607,14 @@ static void omap3_pm_end(void) | |||
614 | { | 607 | { |
615 | suspend_state = PM_SUSPEND_ON; | 608 | suspend_state = PM_SUSPEND_ON; |
616 | omap_uart_enable_irqs(1); | 609 | omap_uart_enable_irqs(1); |
610 | enable_hlt(); | ||
617 | return; | 611 | return; |
618 | } | 612 | } |
619 | 613 | ||
620 | static struct platform_suspend_ops omap_pm_ops = { | 614 | static struct platform_suspend_ops omap_pm_ops = { |
621 | .begin = omap3_pm_begin, | 615 | .begin = omap3_pm_begin, |
622 | .end = omap3_pm_end, | 616 | .end = omap3_pm_end, |
623 | .prepare = omap3_pm_prepare, | ||
624 | .enter = omap3_pm_enter, | 617 | .enter = omap3_pm_enter, |
625 | .finish = omap3_pm_finish, | ||
626 | .valid = suspend_valid_only_mem, | 618 | .valid = suspend_valid_only_mem, |
627 | }; | 619 | }; |
628 | #endif /* CONFIG_SUSPEND */ | 620 | #endif /* CONFIG_SUSPEND */ |
@@ -925,12 +917,29 @@ void omap3_pm_off_mode_enable(int enable) | |||
925 | state = PWRDM_POWER_RET; | 917 | state = PWRDM_POWER_RET; |
926 | 918 | ||
927 | #ifdef CONFIG_CPU_IDLE | 919 | #ifdef CONFIG_CPU_IDLE |
928 | omap3_cpuidle_update_states(); | 920 | /* |
921 | * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot | ||
922 | * enable OFF mode in a stable form for previous revisions, restrict | ||
923 | * instead to RET | ||
924 | */ | ||
925 | if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) | ||
926 | omap3_cpuidle_update_states(state, PWRDM_POWER_RET); | ||
927 | else | ||
928 | omap3_cpuidle_update_states(state, state); | ||
929 | #endif | 929 | #endif |
930 | 930 | ||
931 | list_for_each_entry(pwrst, &pwrst_list, node) { | 931 | list_for_each_entry(pwrst, &pwrst_list, node) { |
932 | pwrst->next_state = state; | 932 | if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) && |
933 | omap_set_pwrdm_state(pwrst->pwrdm, state); | 933 | pwrst->pwrdm == core_pwrdm && |
934 | state == PWRDM_POWER_OFF) { | ||
935 | pwrst->next_state = PWRDM_POWER_RET; | ||
936 | WARN_ONCE(1, | ||
937 | "%s: Core OFF disabled due to errata i583\n", | ||
938 | __func__); | ||
939 | } else { | ||
940 | pwrst->next_state = state; | ||
941 | } | ||
942 | omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); | ||
934 | } | 943 | } |
935 | } | 944 | } |
936 | 945 | ||
@@ -1002,6 +1011,17 @@ void omap_push_sram_idle(void) | |||
1002 | save_secure_ram_context_sz); | 1011 | save_secure_ram_context_sz); |
1003 | } | 1012 | } |
1004 | 1013 | ||
1014 | static void __init pm_errata_configure(void) | ||
1015 | { | ||
1016 | if (cpu_is_omap3630()) { | ||
1017 | pm34xx_errata |= PM_RTA_ERRATUM_i608; | ||
1018 | /* Enable the l2 cache toggling in sleep logic */ | ||
1019 | enable_omap3630_toggle_l2_on_restore(); | ||
1020 | if (omap_rev() < OMAP3630_REV_ES1_2) | ||
1021 | pm34xx_errata |= PM_SDRC_WAKEUP_ERRATUM_i583; | ||
1022 | } | ||
1023 | } | ||
1024 | |||
1005 | static int __init omap3_pm_init(void) | 1025 | static int __init omap3_pm_init(void) |
1006 | { | 1026 | { |
1007 | struct power_state *pwrst, *tmp; | 1027 | struct power_state *pwrst, *tmp; |
@@ -1011,6 +1031,8 @@ static int __init omap3_pm_init(void) | |||
1011 | if (!cpu_is_omap34xx()) | 1031 | if (!cpu_is_omap34xx()) |
1012 | return -ENODEV; | 1032 | return -ENODEV; |
1013 | 1033 | ||
1034 | pm_errata_configure(); | ||
1035 | |||
1014 | printk(KERN_ERR "Power Management for TI OMAP3.\n"); | 1036 | printk(KERN_ERR "Power Management for TI OMAP3.\n"); |
1015 | 1037 | ||
1016 | /* XXX prcm_setup_regs needs to be before enabling hw | 1038 | /* XXX prcm_setup_regs needs to be before enabling hw |
@@ -1058,6 +1080,14 @@ static int __init omap3_pm_init(void) | |||
1058 | pm_idle = omap3_pm_idle; | 1080 | pm_idle = omap3_pm_idle; |
1059 | omap3_idle_init(); | 1081 | omap3_idle_init(); |
1060 | 1082 | ||
1083 | /* | ||
1084 | * RTA is disabled during initialization as per erratum i608 | ||
1085 | * it is safer to disable RTA by the bootloader, but we would like | ||
1086 | * to be doubly sure here and prevent any mishaps. | ||
1087 | */ | ||
1088 | if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608)) | ||
1089 | omap3630_ctrl_disable_rta(); | ||
1090 | |||
1061 | clkdm_add_wkdep(neon_clkdm, mpu_clkdm); | 1091 | clkdm_add_wkdep(neon_clkdm, mpu_clkdm); |
1062 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { | 1092 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { |
1063 | omap3_secure_ram_storage = | 1093 | omap3_secure_ram_storage = |