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 >
# include < a s m / h a r d w a r e . h >
# include < a s m / a r c h / p x a - r e g s . h >
2005-04-26 02:38:55 +04:00
# ifdef C O N F I G _ P X A 2 7 x / / w o r k a r o u n d f o r E r r a t a 5 0
# 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
# endif
2005-04-17 02:20:36 +04:00
.text
/ *
* pxa_ c p u _ s u s p e n d ( )
*
2005-10-28 19:25:01 +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
2005-04-17 02:20:36 +04:00
* /
ENTRY( p x a _ c p u _ s u s p e n d )
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
mra r2 , r3 , a c c0
2005-04-26 02:38:55 +04:00
# endif
2005-04-17 02:20:36 +04:00
stmfd s p ! , { r2 - r12 , l r } @ save registers on stack
@ get coprocessor registers
mrc p14 , 0 , r3 , c6 , c0 , 0 @ clock configuration, for turbo mode
mrc p15 , 0 , r4 , c15 , c1 , 0 @ CP access reg
mrc p15 , 0 , r5 , c13 , c0 , 0 @ PID
mrc p15 , 0 , r6 , c3 , c0 , 0 @ domain ID
mrc p15 , 0 , r7 , c2 , c0 , 0 @ translation table base addr
mrc p15 , 0 , r8 , c1 , c1 , 0 @ auxiliary control reg
mrc p15 , 0 , r9 , c1 , c0 , 0 @ control reg
bic r3 , r3 , #2 @ clear frequency change bit
@ store them plus current virtual stack ptr on stack
mov r10 , s p
stmfd s p ! , { r3 - r10 }
2005-10-28 19:25:01 +04:00
mov r5 , r0 @ save sleep mode
2005-04-17 02:20:36 +04:00
@ preserve phys address of stack
mov r0 , s p
bl s l e e p _ p h y s _ s p
ldr r1 , =sleep_save_sp
str r0 , [ r1 ]
@ clean data cache
bl x s c a l e _ f l u s h _ k e r n _ c a c h e _ a l l
@ Put the processor to sleep
@ (also workaround for sighting 28071)
@ prepare value for sleep mode
2005-10-28 19:25:01 +04:00
mov r1 , r5 @ 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
# ifdef C O N F I G _ P X A 2 7 x
@ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
ldr r6 , =MDREFR_KDIV
orr r5 , r5 , r6
# endif
2005-04-17 02:20:36 +04:00
2005-04-26 02:38:55 +04:00
# ifdef C O N F I G _ P X A 2 5 x
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
2005-04-26 02:38:55 +04:00
# endif
# ifdef C O N F I G _ P X A 2 7 x
@ 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
# endif
2005-04-17 02:20:36 +04:00
@ align execution to a cache line
b 1 f
.ltorg
.align 5
1 :
@ All needed values are now in registers.
@ These last instructions should be in cache
2005-04-26 02:38:55 +04:00
# if d e f i n e d ( C O N F I G _ P X A 2 5 x ) | | d e f i n e d ( C O N F I G _ P X A 2 7 x )
2005-04-17 02:20:36 +04:00
@ 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
# endif
@ 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
/ *
* cpu_ p x a _ r e s u m e ( )
*
* 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
*
* Note : Yes, p a r t o f t h e f o l l o w i n g c o d e i s l o c a t e d i n t o t h e . d a t a s e c t i o n .
* This i s t o a l l o w s l e e p _ s a v e _ s p t o b e a c c e s s e d w i t h a r e l a t i v e l o a d
* while w e c a n ' t r e l y o n a n y M M U t r a n s l a t i o n . W e c o u l d h a v e p u t
* sleep_ s a v e _ s p i n t h e . t e x t s e c t i o n a s w e l l , b u t s o m e s e t u p s m i g h t
* insist o n i t t o b e t r u l y r e a d - o n l y .
* /
.data
.align 5
ENTRY( p x a _ c p u _ r e s u m e )
2006-06-25 15:01:48 +04:00
mov r0 , #P S R _ I _ B I T | P S R _ F _ B I T | S V C _ M O D E @ s e t S V C , i r q s o f f
2005-04-17 02:20:36 +04:00
msr c p s r _ c , r0
ldr r0 , s l e e p _ s a v e _ s p @ stack phys addr
ldr r2 , =resume_after_mmu @ its absolute virtual address
ldmfd r0 , { r3 - r9 , s p } @ CP regs + virt stack ptr
mov r1 , #0
mcr p15 , 0 , r1 , c8 , c7 , 0 @ invalidate I & D TLBs
mcr p15 , 0 , r1 , c7 , c7 , 0 @ invalidate I & D caches, BTB
# ifdef C O N F I G _ X S C A L E _ C A C H E _ E R R A T A
bic r9 , r9 , #0x0004 @ see cpu_xscale_proc_init
# endif
mcr p14 , 0 , r3 , c6 , c0 , 0 @ clock configuration, turbo mode.
mcr p15 , 0 , r4 , c15 , c1 , 0 @ CP access reg
mcr p15 , 0 , r5 , c13 , c0 , 0 @ PID
mcr p15 , 0 , r6 , c3 , c0 , 0 @ domain ID
mcr p15 , 0 , r7 , c2 , c0 , 0 @ translation table base addr
mcr p15 , 0 , r8 , c1 , c1 , 0 @ auxiliary control reg
b r e s u m e _ t u r n _ o n _ m m u @ cache align execution
.align 5
resume_turn_on_mmu :
mcr p15 , 0 , r9 , c1 , c0 , 0 @ turn on MMU, caches, etc.
@ Let us ensure we jump to resume_after_mmu only when the mcr above
@ actually took effect. They call it the "cpwait" operation.
mrc p15 , 0 , r1 , c2 , c0 , 0 @ queue a dependency on CP15
sub p c , r2 , r1 , l s r #32 @ jump to virtual addr
nop
nop
nop
sleep_save_sp :
.word 0 @ preserve stack phys ptr here
.text
resume_after_mmu :
# ifdef C O N F I G _ X S C A L E _ C A C H E _ E R R A T A
bl c p u _ x s c a l e _ p r o c _ i n i t
# endif
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