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
2013-09-22 22:29:57 +02:00
# include <asm/proc-fns.h>
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
2013-11-24 12:02:35 -06:00
# ifdef CONFIG_PM
2013-09-22 22:29:57 +02:00
extern void at91_pm_set_standby ( void ( * at91_standby ) ( void ) ) ;
2013-11-24 12:02:35 -06:00
# else
static inline void at91_pm_set_standby ( void ( * at91_standby ) ( void ) ) { }
# endif
2013-09-22 22:29:57 +02:00
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 .
*/
2013-10-16 16:24:56 +02:00
static inline void at91_ddr_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 . */
2013-10-16 16:24:56 +02:00
u32 lpr0 , lpr1 = 0 ;
u32 saved_lpr0 , saved_lpr1 = 0 ;
2010-06-21 14:59:27 +01:00
2013-10-16 16:24:56 +02:00
if ( at91_ramc_base [ 1 ] ) {
saved_lpr1 = at91_ramc_read ( 1 , AT91_DDRSDRC_LPR ) ;
lpr1 = saved_lpr1 & ~ AT91_DDRSDRC_LPCB ;
lpr1 | = AT91_DDRSDRC_LPCB_SELF_REFRESH ;
}
2010-06-21 14:59:27 +01:00
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 ) ;
2013-10-16 16:24:56 +02:00
if ( at91_ramc_base [ 1 ] )
at91_ramc_write ( 1 , AT91_DDRSDRC_LPR , lpr1 ) ;
2010-06-21 14:59:27 +01:00
2012-01-25 00:56:08 +01:00
cpu_do_idle ( ) ;
at91_ramc_write ( 0 , AT91_DDRSDRC_LPR , saved_lpr0 ) ;
2013-10-16 16:24:56 +02:00
if ( at91_ramc_base [ 1 ] )
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-10-16 16:24:56 +02:00
static inline void at91sam9_sdram_standby ( void )
2013-01-25 22:44:17 +00:00
{
2013-10-16 16:24:56 +02:00
u32 lpr0 , lpr1 = 0 ;
u32 saved_lpr0 , saved_lpr1 = 0 ;
2013-01-25 22:44:17 +00:00
2013-10-16 16:24:56 +02:00
if ( at91_ramc_base [ 1 ] ) {
saved_lpr1 = at91_ramc_read ( 1 , AT91_SDRAMC_LPR ) ;
lpr1 = saved_lpr1 & ~ AT91_SDRAMC_LPCB ;
lpr1 | = AT91_SDRAMC_LPCB_SELF_REFRESH ;
}
2013-01-25 22:44:17 +00:00
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 ) ;
2013-10-16 16:24:56 +02:00
if ( at91_ramc_base [ 1 ] )
at91_ramc_write ( 1 , AT91_SDRAMC_LPR , lpr1 ) ;
2013-01-25 22:44:17 +00:00
cpu_do_idle ( ) ;
at91_ramc_write ( 0 , AT91_SDRAMC_LPR , saved_lpr0 ) ;
2013-10-16 16:24:56 +02:00
if ( at91_ramc_base [ 1 ] )
at91_ramc_write ( 1 , AT91_SDRAMC_LPR , saved_lpr1 ) ;
2009-11-01 18:40:50 +01:00
}
2012-01-25 00:56:06 +01:00
# endif