2008-01-29 02:00:02 +03:00
/*
* Static Memory Controller
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/io.h>
2011-04-23 00:03:11 +04:00
# include <linux/syscore_ops.h>
2008-01-29 02:00:02 +03:00
2008-11-28 19:04:54 +03:00
# include <mach/hardware.h>
2010-11-03 18:29:35 +03:00
# include <mach/smemc.h>
2008-01-29 02:00:02 +03:00
# ifdef CONFIG_PM
static unsigned long msc [ 2 ] ;
static unsigned long sxcnfg , memclkcfg ;
static unsigned long csadrcfg [ 4 ] ;
2011-04-23 00:03:11 +04:00
static int pxa3xx_smemc_suspend ( void )
2008-01-29 02:00:02 +03:00
{
2010-11-03 18:29:35 +03:00
msc [ 0 ] = __raw_readl ( MSC0 ) ;
msc [ 1 ] = __raw_readl ( MSC1 ) ;
sxcnfg = __raw_readl ( SXCNFG ) ;
memclkcfg = __raw_readl ( MEMCLKCFG ) ;
csadrcfg [ 0 ] = __raw_readl ( CSADRCFG0 ) ;
csadrcfg [ 1 ] = __raw_readl ( CSADRCFG1 ) ;
csadrcfg [ 2 ] = __raw_readl ( CSADRCFG2 ) ;
csadrcfg [ 3 ] = __raw_readl ( CSADRCFG3 ) ;
2008-01-29 02:00:02 +03:00
return 0 ;
}
2011-04-23 00:03:11 +04:00
static void pxa3xx_smemc_resume ( void )
2008-01-29 02:00:02 +03:00
{
2010-11-03 18:29:35 +03:00
__raw_writel ( msc [ 0 ] , MSC0 ) ;
__raw_writel ( msc [ 1 ] , MSC1 ) ;
__raw_writel ( sxcnfg , SXCNFG ) ;
__raw_writel ( memclkcfg , MEMCLKCFG ) ;
__raw_writel ( csadrcfg [ 0 ] , CSADRCFG0 ) ;
__raw_writel ( csadrcfg [ 1 ] , CSADRCFG1 ) ;
__raw_writel ( csadrcfg [ 2 ] , CSADRCFG2 ) ;
__raw_writel ( csadrcfg [ 3 ] , CSADRCFG3 ) ;
2013-01-13 15:49:47 +04:00
/* CSMSADRCFG wakes up in its default state (0), so we need to set it */
__raw_writel ( 0x2 , CSMSADRCFG ) ;
2008-01-29 02:00:02 +03:00
}
2011-04-23 00:03:11 +04:00
static struct syscore_ops smemc_syscore_ops = {
2008-01-29 02:00:02 +03:00
. suspend = pxa3xx_smemc_suspend ,
. resume = pxa3xx_smemc_resume ,
} ;
static int __init smemc_init ( void )
{
2013-01-13 15:49:47 +04:00
if ( cpu_is_pxa3xx ( ) ) {
/*
* The only documentation we have on the
* Chip Select Configuration Register ( CSMSADRCFG ) is that
* it must be programmed to 0x2 .
* Moreover , in the bit definitions , the second bit
* ( CSMSADRCFG [ 1 ] ) is called " SETALWAYS " .
* Other bits are reserved in this register .
*/
__raw_writel ( 0x2 , CSMSADRCFG ) ;
2011-04-23 00:03:11 +04:00
register_syscore_ops ( & smemc_syscore_ops ) ;
2013-01-13 15:49:47 +04:00
}
2008-01-29 02:00:02 +03:00
2011-04-23 00:03:11 +04:00
return 0 ;
2008-01-29 02:00:02 +03:00
}
subsys_initcall ( smemc_init ) ;
# endif