2005-04-17 02:20:36 +04:00
/ *
* Low- l e v e l P X A 2 5 0 / 2 1 0 s l e e p / w a k e U p s u p p o r t
*
* Initial S A 1 1 1 0 c o d e :
* Copyright ( c ) 2 0 0 1 C l i f f B r a k e < c b r a k e @accelent.com>
*
* Adapted f o r P X A b y N i c o l a s P i t r e :
* Copyright ( c ) 2 0 0 2 M o n t a V i s t a S o f t w a r e , I n c .
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or
* modify i t u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
2008-08-05 19:14:15 +04:00
# include < m a c h / h a r d w a r e . h >
2010-11-03 18:29:35 +03:00
# include < m a c h / s m e m c . h >
2008-08-05 19:14:15 +04:00
# include < m a c h / p x a2 x x - r e g s . h >
2005-04-17 02:20:36 +04:00
2005-04-26 02:38:55 +04:00
# define M D R E F R _ K D I V 0 x20 0 a40 0 0 / / a l l b a n k s
# define C C C R _ S L E E P 0 x00 0 0 0 1 0 7 / / L =7 2 N =2 A =0 P P D I S =0 C P D I S =0
2005-04-17 02:20:36 +04:00
.text
2008-01-29 02:00:02 +03:00
# ifdef C O N F I G _ P X A 3 x x
/ *
* pxa3 x x _ c p u _ s u s p e n d ( ) - f o r c e s C P U i n t o s l e e p s t a t e ( S 2 D 3 C 4 )
*
2011-02-06 20:41:26 +03:00
* r0 = v : p o f f s e t
2008-01-29 02:00:02 +03:00
* /
ENTRY( p x a3 x x _ c p u _ s u s p e n d )
# ifndef C O N F I G _ I W M M X T
mra r2 , r3 , a c c0
# endif
stmfd s p ! , { r2 - r12 , l r } @ save registers on stack
2011-02-06 20:41:26 +03:00
mov r1 , r0
ldr r3 , =pxa_cpu_resume @ resume function
bl c p u _ s u s p e n d
2008-01-29 02:00:02 +03:00
mov r0 , #0x06 @ S2D3C4 mode
mcr p14 , 0 , r0 , c7 , c0 , 0 @ enter sleep
20 : b 2 0 b @ waiting for sleep
# endif / * C O N F I G _ P X A 3 x x * /
2008-01-05 01:43:36 +03:00
# ifdef C O N F I G _ P X A 2 7 x
2007-07-18 14:40:13 +04:00
/ *
* pxa2 7 x _ c p u _ s u s p e n d ( )
*
* Forces C P U i n t o s l e e p s t a t e .
*
* r0 = v a l u e f o r P W R M O D E M f i e l d f o r d e s i r e d s l e e p s t a t e
2011-02-06 20:41:26 +03:00
* r1 = v : p o f f s e t
2007-07-18 14:40:13 +04:00
* /
ENTRY( p x a27 x _ c p u _ s u s p e n d )
# ifndef C O N F I G _ I W M M X T
mra r2 , r3 , a c c0
# endif
stmfd s p ! , { r2 - r12 , l r } @ save registers on stack
2011-02-06 20:41:26 +03:00
mov r4 , r0 @ save sleep mode
ldr r3 , =pxa_cpu_resume @ resume function
bl c p u _ s u s p e n d
2005-04-17 02:20:36 +04:00
@ Put the processor to sleep
@ (also workaround for sighting 28071)
@ prepare value for sleep mode
2011-02-06 20:41:26 +03:00
mov r1 , r4 @ sleep mode
2005-04-17 02:20:36 +04:00
2005-04-26 02:38:55 +04:00
@ prepare pointer to physical address 0 (virtual mapping in generic.c)
mov r2 , #U N C A C H E D _ P H Y S _ 0
@ prepare SDRAM refresh settings
2005-04-17 02:20:36 +04:00
ldr r4 , =MDREFR
ldr r5 , [ r4 ]
2005-04-26 02:38:55 +04:00
@ enable SDRAM self-refresh mode
2005-04-17 02:20:36 +04:00
orr r5 , r5 , #M D R E F R _ S L F R S H
2005-04-26 02:38:55 +04:00
@ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
ldr r6 , =MDREFR_KDIV
orr r5 , r5 , r6
2005-04-17 02:20:36 +04:00
2007-07-18 14:40:13 +04:00
@ Intel PXA270 Specification Update notes problems sleeping
@ with core operating above 91 MHz
@ (see Errata 50, ...processor does not exit from sleep...)
ldr r6 , =CCCR
ldr r8 , [ r6 ] @ keep original value for resume
ldr r7 , =CCCR_SLEEP @ prepare CCCR sleep value
mov r0 , #0x2 @ prepare value for CLKCFG
@ align execution to a cache line
b p x a _ c p u _ d o _ s u s p e n d
2008-01-05 01:43:36 +03:00
# endif
2007-07-18 14:40:13 +04:00
2008-01-05 01:43:36 +03:00
# ifdef C O N F I G _ P X A 2 5 x
2007-07-18 14:40:13 +04:00
/ *
2008-01-05 01:43:36 +03:00
* pxa2 5 x _ c p u _ s u s p e n d ( )
2007-07-18 14:40:13 +04:00
*
* Forces C P U i n t o s l e e p s t a t e .
*
* r0 = v a l u e f o r P W R M O D E M f i e l d f o r d e s i r e d s l e e p s t a t e
2011-02-06 20:41:26 +03:00
* r1 = v : p o f f s e t
2007-07-18 14:40:13 +04:00
* /
ENTRY( p x a25 x _ c p u _ s u s p e n d )
stmfd s p ! , { r2 - r12 , l r } @ save registers on stack
2011-02-06 20:41:26 +03:00
mov r4 , r0 @ save sleep mode
ldr r3 , =pxa_cpu_resume @ resume function
bl c p u _ s u s p e n d
2007-07-18 14:40:13 +04:00
@ prepare value for sleep mode
2011-02-06 20:41:26 +03:00
mov r1 , r4 @ sleep mode
2007-07-18 14:40:13 +04:00
@ prepare pointer to physical address 0 (virtual mapping in generic.c)
mov r2 , #U N C A C H E D _ P H Y S _ 0
@ prepare SDRAM refresh settings
ldr r4 , =MDREFR
ldr r5 , [ r4 ]
@ enable SDRAM self-refresh mode
orr r5 , r5 , #M D R E F R _ S L F R S H
2005-04-17 02:20:36 +04:00
@ Intel PXA255 Specification Update notes problems
@ about suspending with PXBus operating above 133MHz
@ (see Errata 31, GPIO output signals, ... unpredictable in sleep
@
@ We keep the change-down close to the actual suspend on SDRAM
@ as possible to eliminate messing about with the refresh clock
@ as the system will restore with the original speed settings
@
@ Ben Dooks, 13-Sep-2004
ldr r6 , =CCCR
ldr r8 , [ r6 ] @ keep original value for resume
@ ensure x1 for run and turbo mode with memory clock
bic r7 , r8 , #C C C R _ M _ M A S K | C C C R _ N _ M A S K
orr r7 , r7 , #( 1 < < 5 ) | ( 2 < < 7 )
@ check that the memory frequency is within limits
and r14 , r7 , #C C C R _ L _ M A S K
teq r14 , #1
bicne r7 , r7 , #C C C R _ L _ M A S K
orrne r7 , r7 , #1 @@ 99.53MHz
@ get ready for the change
@ note, turbo is not preserved over sleep so there is no
@ point in preserving it here. we save it on the stack with the
@ other CP registers instead.
mov r0 , #0
mcr p14 , 0 , r0 , c6 , c0 , 0
orr r0 , r0 , #2 @ initiate change bit
2007-07-18 14:40:13 +04:00
b p x a _ c p u _ d o _ s u s p e n d
2008-01-05 01:43:36 +03:00
# endif
2005-04-17 02:20:36 +04:00
.ltorg
.align 5
2007-07-18 14:40:13 +04:00
pxa_cpu_do_suspend :
2005-04-17 02:20:36 +04:00
@ All needed values are now in registers.
@ These last instructions should be in cache
@ initiate the frequency change...
str r7 , [ r6 ]
mcr p14 , 0 , r0 , c6 , c0 , 0
@ restore the original cpu speed value for resume
str r8 , [ r6 ]
2005-04-26 02:38:55 +04:00
@ need 6 13-MHz cycles before changing PWRMODE
@ just set frequency to 91-MHz... 6*91/13 = 42
mov r0 , #42
10 : subs r0 , r0 , #1
bne 1 0 b
@ Do not reorder...
@ Intel PXA270 Specification Update notes problems performing
@ external accesses after SDRAM is put in self-refresh mode
@ (see Errata 39 ...hangs when entering self-refresh mode)
2005-04-17 02:20:36 +04:00
@ force address lines low by reading at physical address 0
ldr r3 , [ r2 ]
2005-04-26 02:38:55 +04:00
@ put SDRAM into self-refresh
str r5 , [ r4 ]
2005-04-17 02:20:36 +04:00
@ enter sleep mode
2005-04-26 02:38:55 +04:00
mcr p14 , 0 , r1 , c7 , c0 , 0 @ PWRMODE
2005-04-17 02:20:36 +04:00
20 : b 2 0 b @ loop waiting for sleep
/ *
2008-01-05 01:43:36 +03:00
* pxa_ c p u _ r e s u m e ( )
2005-04-17 02:20:36 +04:00
*
* entry p o i n t f r o m b o o t l o a d e r i n t o k e r n e l d u r i n g r e s u m e
* /
.align 5
2011-02-06 20:41:26 +03:00
pxa_cpu_resume :
2005-04-17 02:20:36 +04:00
ldmfd s p ! , { r2 , r3 }
2005-04-26 02:38:55 +04:00
# ifndef C O N F I G _ I W M M X T
2005-04-17 02:20:36 +04:00
mar a c c0 , r2 , r3
2005-04-26 02:38:55 +04:00
# endif
2005-04-17 02:20:36 +04:00
ldmfd s p ! , { r4 - r12 , p c } @ return to caller