diff options
| -rw-r--r-- | arch/arm/mach-at91/cpuidle.c | 11 | ||||
| -rw-r--r-- | arch/arm/mach-at91/pm.c | 12 | ||||
| -rw-r--r-- | arch/arm/mach-at91/pm.h | 73 |
3 files changed, 51 insertions, 45 deletions
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c index a851e6c98421..555d956b3a57 100644 --- a/arch/arm/mach-at91/cpuidle.c +++ b/arch/arm/mach-at91/cpuidle.c | |||
| @@ -39,20 +39,15 @@ static int at91_enter_idle(struct cpuidle_device *dev, | |||
| 39 | { | 39 | { |
| 40 | struct timeval before, after; | 40 | struct timeval before, after; |
| 41 | int idle_time; | 41 | int idle_time; |
| 42 | u32 saved_lpr; | ||
| 43 | 42 | ||
| 44 | local_irq_disable(); | 43 | local_irq_disable(); |
| 45 | do_gettimeofday(&before); | 44 | do_gettimeofday(&before); |
| 46 | if (index == 0) | 45 | if (index == 0) |
| 47 | /* Wait for interrupt state */ | 46 | /* Wait for interrupt state */ |
| 48 | cpu_do_idle(); | 47 | cpu_do_idle(); |
| 49 | else if (index == 1) { | 48 | else if (index == 1) |
| 50 | asm("b 1f; .align 5; 1:"); | 49 | at91_standby(); |
| 51 | asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ | 50 | |
| 52 | saved_lpr = sdram_selfrefresh_enable(); | ||
| 53 | cpu_do_idle(); | ||
| 54 | sdram_selfrefresh_disable(saved_lpr); | ||
| 55 | } | ||
| 56 | do_gettimeofday(&after); | 51 | do_gettimeofday(&after); |
| 57 | local_irq_enable(); | 52 | local_irq_enable(); |
| 58 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | 53 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 87be5aa18753..d554e6771b4e 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
| @@ -198,7 +198,6 @@ extern u32 at91_slow_clock_sz; | |||
| 198 | 198 | ||
| 199 | static int at91_pm_enter(suspend_state_t state) | 199 | static int at91_pm_enter(suspend_state_t state) |
| 200 | { | 200 | { |
| 201 | u32 saved_lpr; | ||
| 202 | at91_gpio_suspend(); | 201 | at91_gpio_suspend(); |
| 203 | at91_irq_suspend(); | 202 | at91_irq_suspend(); |
| 204 | 203 | ||
| @@ -254,16 +253,7 @@ static int at91_pm_enter(suspend_state_t state) | |||
| 254 | * For ARM 926 based chips, this requirement is weaker | 253 | * For ARM 926 based chips, this requirement is weaker |
| 255 | * as at91sam9 can access a RAM in self-refresh mode. | 254 | * as at91sam9 can access a RAM in self-refresh mode. |
| 256 | */ | 255 | */ |
| 257 | asm volatile ( "mov r0, #0\n\t" | 256 | at91_standby(); |
| 258 | "b 1f\n\t" | ||
| 259 | ".align 5\n\t" | ||
| 260 | "1: mcr p15, 0, r0, c7, c10, 4\n\t" | ||
| 261 | : /* no output */ | ||
| 262 | : /* no input */ | ||
| 263 | : "r0"); | ||
| 264 | saved_lpr = sdram_selfrefresh_enable(); | ||
| 265 | wait_for_interrupt_enable(); | ||
| 266 | sdram_selfrefresh_disable(saved_lpr); | ||
| 267 | break; | 257 | break; |
| 268 | 258 | ||
| 269 | case PM_SUSPEND_ON: | 259 | case PM_SUSPEND_ON: |
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 218d816427c0..bba9ce1aaaec 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | /* | ||
| 2 | * AT91 Power Management | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 David Brownell | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | #ifndef __ARCH_ARM_MACH_AT91_PM | ||
| 12 | #define __ARCH_ARM_MACH_AT91_PM | ||
| 13 | |||
| 1 | #ifdef CONFIG_ARCH_AT91RM9200 | 14 | #ifdef CONFIG_ARCH_AT91RM9200 |
| 2 | #include <mach/at91rm9200_mc.h> | 15 | #include <mach/at91rm9200_mc.h> |
| 3 | 16 | ||
| @@ -11,18 +24,25 @@ | |||
| 11 | * still in self-refresh is "not recommended", but seems to work. | 24 | * still in self-refresh is "not recommended", but seems to work. |
| 12 | */ | 25 | */ |
| 13 | 26 | ||
| 14 | static inline u32 sdram_selfrefresh_enable(void) | 27 | static inline void at91rm9200_standby(void) |
| 15 | { | 28 | { |
| 16 | u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR); | 29 | u32 lpr = at91_sys_read(AT91_SDRAMC_LPR); |
| 17 | 30 | ||
| 18 | at91_sys_write(AT91_SDRAMC_LPR, 0); | 31 | asm volatile( |
| 19 | at91_sys_write(AT91_SDRAMC_SRR, 1); | 32 | "b 1f\n\t" |
| 20 | return saved_lpr; | 33 | ".align 5\n\t" |
| 34 | "1: mcr p15, 0, %0, c7, c10, 4\n\t" | ||
| 35 | " str %0, [%1, %2]\n\t" | ||
| 36 | " str %3, [%1, %4]\n\t" | ||
| 37 | " mcr p15, 0, %0, c7, c0, 4\n\t" | ||
| 38 | " str %5, [%1, %2]" | ||
| 39 | : | ||
| 40 | : "r" (0), "r" (AT91_BASE_SYS), "r" (AT91_SDRAMC_LPR), | ||
| 41 | "r" (1), "r" (AT91_SDRAMC_SRR), | ||
| 42 | "r" (lpr)); | ||
| 21 | } | 43 | } |
| 22 | 44 | ||
| 23 | #define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr) | 45 | #define at91_standby at91rm9200_standby |
| 24 | #define wait_for_interrupt_enable() asm volatile ("mcr p15, 0, %0, c7, c0, 4" \ | ||
| 25 | : : "r" (0)) | ||
| 26 | 46 | ||
| 27 | #elif defined(CONFIG_ARCH_AT91SAM9G45) | 47 | #elif defined(CONFIG_ARCH_AT91SAM9G45) |
| 28 | #include <mach/at91sam9_ddrsdr.h> | 48 | #include <mach/at91sam9_ddrsdr.h> |
| @@ -30,14 +50,12 @@ static inline u32 sdram_selfrefresh_enable(void) | |||
| 30 | /* We manage both DDRAM/SDRAM controllers, we need more than one value to | 50 | /* We manage both DDRAM/SDRAM controllers, we need more than one value to |
| 31 | * remember. | 51 | * remember. |
| 32 | */ | 52 | */ |
| 33 | static u32 saved_lpr1; | 53 | static inline void at91sam9g45_standby(void) |
| 34 | |||
| 35 | static inline u32 sdram_selfrefresh_enable(void) | ||
| 36 | { | 54 | { |
| 37 | /* Those tow values allow us to delay self-refresh activation | 55 | /* Those two values allow us to delay self-refresh activation |
| 38 | * to the maximum. */ | 56 | * to the maximum. */ |
| 39 | u32 lpr0, lpr1; | 57 | u32 lpr0, lpr1; |
| 40 | u32 saved_lpr0; | 58 | u32 saved_lpr0, saved_lpr1; |
| 41 | 59 | ||
| 42 | saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); | 60 | saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); |
| 43 | lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; | 61 | lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; |
| @@ -51,15 +69,13 @@ static inline u32 sdram_selfrefresh_enable(void) | |||
| 51 | at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); | 69 | at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); |
| 52 | at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); | 70 | at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); |
| 53 | 71 | ||
| 54 | return saved_lpr0; | 72 | cpu_do_idle(); |
| 73 | |||
| 74 | at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); | ||
| 75 | at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); | ||
| 55 | } | 76 | } |
| 56 | 77 | ||
| 57 | #define sdram_selfrefresh_disable(saved_lpr0) \ | 78 | #define at91_standby at91sam9g45_standby |
| 58 | do { \ | ||
| 59 | at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \ | ||
| 60 | at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \ | ||
| 61 | } while (0) | ||
| 62 | #define wait_for_interrupt_enable() cpu_do_idle() | ||
| 63 | 79 | ||
| 64 | #else | 80 | #else |
| 65 | #include <mach/at91sam9_sdramc.h> | 81 | #include <mach/at91sam9_sdramc.h> |
| @@ -72,18 +88,23 @@ static inline u32 sdram_selfrefresh_enable(void) | |||
| 72 | #warning Assuming EB1 SDRAM controller is *NOT* used | 88 | #warning Assuming EB1 SDRAM controller is *NOT* used |
| 73 | #endif | 89 | #endif |
| 74 | 90 | ||
| 75 | static inline u32 sdram_selfrefresh_enable(void) | 91 | static inline void at91sam9_standby(void) |
| 76 | { | 92 | { |
| 77 | u32 saved_lpr, lpr; | 93 | u32 saved_lpr, lpr; |
| 78 | 94 | ||
| 79 | saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR); | 95 | saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR); |
| 80 | 96 | ||
| 81 | lpr = saved_lpr & ~AT91_SDRAMC_LPCB; | 97 | lpr = saved_lpr & ~AT91_SDRAMC_LPCB; |
| 82 | at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH); | 98 | at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | |
| 83 | return saved_lpr; | 99 | AT91_SDRAMC_LPCB_SELF_REFRESH); |
| 100 | |||
| 101 | cpu_do_idle(); | ||
| 102 | |||
| 103 | at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr); | ||
| 84 | } | 104 | } |
| 85 | 105 | ||
| 86 | #define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr) | 106 | #define at91_standby at91sam9_standby |
| 87 | #define wait_for_interrupt_enable() cpu_do_idle() | 107 | |
| 108 | #endif | ||
| 88 | 109 | ||
| 89 | #endif | 110 | #endif |
