2007-05-09 09:51:49 +04:00
/ * linux/ a r c h / a r m / p l a t - s3 c24 x x / s l e e p . S
2007-02-11 20:31:01 +03:00
*
* Copyright ( c ) 2 0 0 4 S i m t e c E l e c t r o n i c s
* Ben D o o k s < b e n @simtec.co.uk>
*
* S3 C 2 4 1 0 P o w e r M a n a g e r ( S u s p e n d - T o - R A M ) s u p p o r t
*
* Based o n P X A / S A 1 1 0 0 s l e e p c o d e b y :
* Nicolas P i t r e , ( 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
* Cliff B r a k e , ( c ) 2 0 0 1
*
* 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
* it 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 a s p u b l i s h e d b y
* the F r e e S o f t w a r e F o u n d a t i o n ; either version 2 of the License, or
* ( at y o u r o p t i o n ) a n y l a t e r v e r s i o n .
*
* This p r o g r a m i s d i s t r i b u t e d i n t h e h o p e t h a t i t w i l l b e u s e f u l ,
* but W I T H O U T A N Y W A R R A N T Y ; without even the implied warranty of
* MERCHANTABILITY o r F I T N E S S F O R A P A R T I C U L A R P U R P O S E . S e e t h e
* GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e d e t a i l s .
*
* You s h o u l d h a v e r e c e i v e d a c o p y 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
* along w i t h t h i s p r o g r a m ; if not, write to the Free Software
* Foundation, I n c . , 5 9 T e m p l e P l a c e , S u i t e 3 3 0 , B o s t o n , M A 0 2 1 1 1 - 1 3 0 7 U S A
* /
# 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 >
# include < m a c h / m a p . h >
2007-02-11 20:31:01 +03:00
2008-08-05 19:14:15 +04:00
# include < m a c h / r e g s - g p i o . h >
# include < m a c h / r e g s - c l o c k . h >
# include < m a c h / r e g s - m e m . h >
2008-10-08 01:26:09 +04:00
# include < p l a t / r e g s - s e r i a l . h >
2007-02-11 20:31:01 +03:00
/ * CONFIG_ D E B U G _ R E S U M E i s d a n g e r o u s i f y o u r b o o t l o a d e r d o e s n o t
* reset t h e U A R T c o n f i g u r a t i o n , o n l y e n a b l e i f y o u r e a l l y n e e d t h i s !
* /
/ / # define C O N F I G _ D E B U G _ R E S U M E
.text
2008-12-12 03:24:19 +03:00
/ * s3 c _ c p u _ s a v e
2007-02-11 20:31:01 +03:00
*
* entry :
2009-03-10 14:48:07 +03:00
* r0 = s a v e a d d r e s s ( v i r t u a l a d d r o f s3 c _ s l e e p _ s a v e _ p h y s )
2007-02-11 20:31:01 +03:00
* /
2008-12-12 03:24:19 +03:00
ENTRY( s3 c _ c p u _ s a v e )
2007-02-11 20:31:01 +03:00
stmfd s p ! , { r4 - r12 , l r }
@@ store co-processor registers
2007-02-12 23:05:02 +03:00
mrc p15 , 0 , r4 , c13 , c0 , 0 @ PID
mrc p15 , 0 , r5 , c3 , c0 , 0 @ Domain ID
mrc p15 , 0 , r6 , c2 , c0 , 0 @ translation table base address
mrc p15 , 0 , r7 , c1 , c0 , 0 @ control register
2007-02-11 20:31:01 +03:00
stmia r0 , { r4 - r13 }
2009-03-10 14:48:07 +03:00
@@ write our state back to RAM
bl s3 c _ p m _ c b _ f l u s h c a c h e
2007-02-11 20:31:01 +03:00
2009-03-10 14:48:07 +03:00
@@ jump to final code to send system to sleep
ldr r0 , =pm_cpu_sleep
@@ldr pc, [ r0 ]
ldr r0 , [ r0 ]
mov p c , r0
2007-02-11 20:31:01 +03:00
@@ return to the caller, after having the MMU
@@ turned on, this restores the last bits from the
@@ stack
resume_with_mmu :
ldmfd s p ! , { r4 - r12 , p c }
.ltorg
@@ the next bits sit in the .data segment, even though they
2008-12-12 03:24:06 +03:00
@@ happen to be code... the s3c_sleep_save_phys needs to be
2007-02-11 20:31:01 +03:00
@@ accessed by the resume code before it can restore the MMU.
@@ This means that the variable has to be close enough for the
@@ code to read it... since the .text segment needs to be RO,
@@ the data segment can be the only place to put this code.
.data
2008-12-12 03:24:06 +03:00
.global s3c_sleep_save_phys
s3c_sleep_save_phys :
2007-02-11 20:31:01 +03:00
.word 0
2007-09-30 12:59:15 +04:00
/ * sleep m a g i c , t o a l l o w t h e b o o t l o a d e r t o c h e c k f o r a n v a l i d
* image t o r e s u m e t o . M u s t b e t h e f i r s t w o r d b e f o r e t h e
2008-12-12 03:24:19 +03:00
* s3 c _ c p u _ r e s u m e e n t r y .
2007-09-30 12:59:15 +04:00
* /
.word 0x2bedf00d
2008-12-12 03:24:19 +03:00
/ * s3 c _ c p u _ r e s u m e
2007-02-11 20:31:01 +03:00
*
* resume c o d e e n t r y f o r b o o t l o a d e r t o c a l l
*
* we m u s t p u t t h i s c o d e h e r e i n t h e d a t a s e g m e n t a s w e h a v e n o
* other w a y o f r e s t o r i n g t h e s t a c k p o i n t e r a f t e r s l e e p , a n d w e
* must n o t w r i t e t o t h e c o d e s e g m e n t ( c o d e i s r e a d - o n l y )
* /
2008-12-12 03:24:19 +03:00
ENTRY( s3 c _ c p u _ r e s u m e )
2007-02-11 20:31:01 +03:00
mov r0 , #P S R _ I _ B I T | P S R _ F _ B I T | S V C _ M O D E
msr c p s r _ c , r0
@@ load UART to allow us to print the two characters for
@@ resume debug
mov r2 , #S 3 C 2 4 X X _ P A _ U A R T & 0 x f f00 0 0 0 0
orr r2 , r2 , #S 3 C 2 4 X X _ P A _ U A R T & 0 x f f00 0
# if 0
/* SMDK2440 LED set */
mov r14 , #S 3 C 2 4 X X _ P A _ G P I O
ldr r12 , [ r14 , #0x54 ]
bic r12 , r12 , #3 < < 4
orr r12 , r12 , #1 < < 7
str r12 , [ r14 , #0x54 ]
# endif
# ifdef C O N F I G _ D E B U G _ R E S U M E
mov r3 , #' L '
strb r3 , [ r2 , #S 3 C 2 4 1 0 _ U T X H ]
1001 :
ldrb r14 , [ r3 , #S 3 C 2 4 1 0 _ U T R S T A T ]
tst r14 , #S 3 C 2 4 1 0 _ U T R S T A T _ T X E
beq 1 0 0 1 b
# endif / * C O N F I G _ D E B U G _ R E S U M E * /
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
2008-12-12 03:24:06 +03:00
ldr r0 , s3 c _ s l e e p _ s a v e _ p h y s @ address of restore block
2007-02-11 20:31:01 +03:00
ldmia r0 , { r4 - r13 }
2007-02-12 23:05:02 +03:00
mcr p15 , 0 , r4 , c13 , c0 , 0 @ PID
mcr p15 , 0 , r5 , c3 , c0 , 0 @ Domain ID
mcr p15 , 0 , r6 , c2 , c0 , 0 @ translation table base
2007-02-11 20:31:01 +03:00
# ifdef C O N F I G _ D E B U G _ R E S U M E
mov r3 , #' R '
strb r3 , [ r2 , #S 3 C 2 4 1 0 _ U T X H ]
# endif
ldr r2 , =resume_with_mmu
2007-02-12 23:05:02 +03:00
mcr p15 , 0 , r7 , c1 , c0 , 0 @ turn on MMU, etc
2007-02-11 20:31:01 +03:00
nop @ second-to-last before mmu
mov p c , r2 @ go back to virtual address
.ltorg