2012-01-25 03:56:06 +04: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 08:58:53 +04:00
# include <mach/at91_ramc.h>
2011-11-15 22:58:31 +04:00
# include <mach/at91rm9200_sdramc.h>
2009-11-01 20:40:50 +03: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 03:56:08 +04:00
static inline void at91rm9200_standby ( void )
2009-11-01 20:40:50 +03:00
{
2012-02-13 08:58:53 +04:00
u32 lpr = at91_ramc_read ( 0 , AT91RM9200_SDRAMC_LPR ) ;
2012-01-25 03:56:08 +04: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-15 22:58:31 +04:00
: " r " ( 0 ) , " r " ( AT91_BASE_SYS ) , " r " ( AT91RM9200_SDRAMC_LPR ) ,
" r " ( 1 ) , " r " ( AT91RM9200_SDRAMC_SRR ) ,
2012-01-25 03:56:08 +04:00
" r " ( lpr ) ) ;
2009-11-01 20:40:50 +03:00
}
2010-06-21 17:59:27 +04:00
/* We manage both DDRAM/SDRAM controllers, we need more than one value to
* remember .
*/
2012-01-25 03:56:08 +04:00
static inline void at91sam9g45_standby ( void )
2010-06-21 17:59:27 +04:00
{
2012-01-25 03:56:08 +04:00
/* Those two values allow us to delay self-refresh activation
2010-06-21 17:59:27 +04:00
* to the maximum . */
u32 lpr0 , lpr1 ;
2012-01-25 03:56:08 +04:00
u32 saved_lpr0 , saved_lpr1 ;
2010-06-21 17:59:27 +04: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 03:56:08 +04: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 17:59:27 +04:00
}
2012-04-06 07:51:50 +04:00
# ifdef CONFIG_SOC_AT91SAM9263
2009-11-01 20:40:50 +03:00
/*
* FIXME either or both the SDRAM controllers ( EB0 , EB1 ) might be in use ;
* handle those cases both here and in the Suspend - To - RAM support .
*/
# warning Assuming EB1 SDRAM controller is *NOT* used
# endif
2012-01-25 03:56:08 +04:00
static inline void at91sam9_standby ( void )
2009-11-01 20:40:50 +03:00
{
u32 saved_lpr , lpr ;
2010-06-21 17:59:27 +04:00
saved_lpr = at91_ramc_read ( 0 , AT91_SDRAMC_LPR ) ;
2009-11-01 20:40:50 +03:00
lpr = saved_lpr & ~ AT91_SDRAMC_LPCB ;
2012-01-25 03:56:05 +04:00
at91_ramc_write ( 0 , AT91_SDRAMC_LPR , lpr |
AT91_SDRAMC_LPCB_SELF_REFRESH ) ;
2012-01-25 03:56:08 +04:00
cpu_do_idle ( ) ;
at91_ramc_write ( 0 , AT91_SDRAMC_LPR , saved_lpr ) ;
2009-11-01 20:40:50 +03:00
}
2012-01-25 03:56:06 +04:00
# endif