2012-01-25 00:56:06 +01:00
/*
* AT91 Power Management
*
* Copyright ( C ) 2005 David Brownell
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*/
# ifndef __ARCH_ARM_MACH_AT91_PM
# define __ARCH_ARM_MACH_AT91_PM
2012-02-13 12:58:53 +08:00
# include <mach/at91_ramc.h>
2011-11-16 02:58:31 +08:00
# include <mach/at91rm9200_sdramc.h>
2009-11-01 18:40:50 +01:00
/*
* The AT91RM9200 goes into self - refresh mode with this command , and will
* terminate self - refresh automatically on the next SDRAM access .
*
* Self - refresh mode is exited as soon as a memory access is made , but we don ' t
* know for sure when that happens . However , we need to restore the low - power
* mode if it was enabled before going idle . Restoring low - power mode while
* still in self - refresh is " not recommended " , but seems to work .
*/
2012-01-25 00:56:08 +01:00
static inline void at91rm9200_standby ( void )
2009-11-01 18:40:50 +01:00
{
2012-02-13 12:58:53 +08:00
u32 lpr = at91_ramc_read ( 0 , AT91RM9200_SDRAMC_LPR ) ;
2012-01-25 00:56:08 +01:00
asm volatile (
" b 1f \n \t "
" .align 5 \n \t "
" 1: mcr p15, 0, %0, c7, c10, 4 \n \t "
" str %0, [%1, %2] \n \t "
" str %3, [%1, %4] \n \t "
" mcr p15, 0, %0, c7, c0, 4 \n \t "
" str %5, [%1, %2] "
:
2011-11-16 02:58:31 +08:00
: " r " ( 0 ) , " r " ( AT91_BASE_SYS ) , " r " ( AT91RM9200_SDRAMC_LPR ) ,
" r " ( 1 ) , " r " ( AT91RM9200_SDRAMC_SRR ) ,
2012-01-25 00:56:08 +01:00
" r " ( lpr ) ) ;
2009-11-01 18:40:50 +01:00
}
2010-06-21 14:59:27 +01:00
/* We manage both DDRAM/SDRAM controllers, we need more than one value to
* remember .
*/
2012-01-25 00:56:08 +01:00
static inline void at91sam9g45_standby ( void )
2010-06-21 14:59:27 +01:00
{
2012-01-25 00:56:08 +01:00
/* Those two values allow us to delay self-refresh activation
2010-06-21 14:59:27 +01:00
* to the maximum . */
u32 lpr0 , lpr1 ;
2012-01-25 00:56:08 +01:00
u32 saved_lpr0 , saved_lpr1 ;
2010-06-21 14:59:27 +01:00
saved_lpr1 = at91_ramc_read ( 1 , AT91_DDRSDRC_LPR ) ;
lpr1 = saved_lpr1 & ~ AT91_DDRSDRC_LPCB ;
lpr1 | = AT91_DDRSDRC_LPCB_SELF_REFRESH ;
saved_lpr0 = at91_ramc_read ( 0 , AT91_DDRSDRC_LPR ) ;
lpr0 = saved_lpr0 & ~ AT91_DDRSDRC_LPCB ;
lpr0 | = AT91_DDRSDRC_LPCB_SELF_REFRESH ;
/* self-refresh mode now */
at91_ramc_write ( 0 , AT91_DDRSDRC_LPR , lpr0 ) ;
at91_ramc_write ( 1 , AT91_DDRSDRC_LPR , lpr1 ) ;
2012-01-25 00:56:08 +01:00
cpu_do_idle ( ) ;
at91_ramc_write ( 0 , AT91_DDRSDRC_LPR , saved_lpr0 ) ;
at91_ramc_write ( 1 , AT91_DDRSDRC_LPR , saved_lpr1 ) ;
2010-06-21 14:59:27 +01:00
}
2013-01-25 22:44:17 +00:00
/* We manage both DDRAM/SDRAM controllers, we need more than one value to
* remember .
2009-11-01 18:40:50 +01:00
*/
2013-01-25 22:44:17 +00:00
static inline void at91sam9263_standby ( void )
{
u32 lpr0 , lpr1 ;
u32 saved_lpr0 , saved_lpr1 ;
saved_lpr1 = at91_ramc_read ( 1 , AT91_SDRAMC_LPR ) ;
lpr1 = saved_lpr1 & ~ AT91_SDRAMC_LPCB ;
lpr1 | = AT91_SDRAMC_LPCB_SELF_REFRESH ;
saved_lpr0 = at91_ramc_read ( 0 , AT91_SDRAMC_LPR ) ;
lpr0 = saved_lpr0 & ~ AT91_SDRAMC_LPCB ;
lpr0 | = AT91_SDRAMC_LPCB_SELF_REFRESH ;
/* self-refresh mode now */
at91_ramc_write ( 0 , AT91_SDRAMC_LPR , lpr0 ) ;
at91_ramc_write ( 1 , AT91_SDRAMC_LPR , lpr1 ) ;
cpu_do_idle ( ) ;
at91_ramc_write ( 0 , AT91_SDRAMC_LPR , saved_lpr0 ) ;
at91_ramc_write ( 1 , AT91_SDRAMC_LPR , saved_lpr1 ) ;
}
2009-11-01 18:40:50 +01:00
2012-01-25 00:56:08 +01:00
static inline void at91sam9_standby ( void )
2009-11-01 18:40:50 +01:00
{
u32 saved_lpr , lpr ;
2010-06-21 14:59:27 +01:00
saved_lpr = at91_ramc_read ( 0 , AT91_SDRAMC_LPR ) ;
2009-11-01 18:40:50 +01:00
lpr = saved_lpr & ~ AT91_SDRAMC_LPCB ;
2012-01-25 00:56:05 +01:00
at91_ramc_write ( 0 , AT91_SDRAMC_LPR , lpr |
AT91_SDRAMC_LPCB_SELF_REFRESH ) ;
2012-01-25 00:56:08 +01:00
cpu_do_idle ( ) ;
at91_ramc_write ( 0 , AT91_SDRAMC_LPR , saved_lpr ) ;
2009-11-01 18:40:50 +01:00
}
2012-01-25 00:56:06 +01:00
# endif