2010-06-16 20:49:48 +04:00
/ *
* OMAP4 4 x x s l e e p c o d e .
*
* Copyright ( C ) 2 0 1 1 T e x a s I n s t r u m e n t s , I n c .
* Santosh S h i l i m k a r < s a n t o s h . s h i l i m k a r @ti.com>
*
* This p r o g r a m i s f r e e s o f t w a r e ,y o u c a n r e d i s t r i b u t e i t a n d / o r m o d i f y
* 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 v e r s i o n 2 a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / s m p _ s c u . h >
# include < a s m / m e m o r y . h >
# include < a s m / h a r d w a r e / c a c h e - l 2 x0 . h >
# include < p l a t / o m a p44 x x . h >
# include < m a c h / o m a p - s e c u r e . h >
# include " c o m m o n . h "
# include " o m a p4 - s a r - l a y o u t . h "
# if d e f i n e d ( C O N F I G _ S M P ) & & d e f i n e d ( C O N F I G _ P M )
.macro DO_SMC
dsb
smc #0
dsb
.endm
ppa_zero_params :
.word 0x0
2011-01-09 00:29:09 +03:00
ppa_por_params :
.word 1 , 0
2010-06-16 20:49:48 +04:00
/ *
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* = = CPU s u s p e n d f i n i s h e r = =
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*
* void o m a p4 _ f i n i s h _ s u s p e n d ( u n s i g n e d l o n g c p u _ s t a t e )
*
* This f u n c t i o n c o d e s a v e s t h e C P U c o n t e x t a n d p e r f o r m s t h e C P U
* power d o w n s e q u e n c e . C a l l i n g W F I e f f e c t i v e l y c h a n g e s t h e C P U
* power d o m a i n s s t a t e s t o t h e d e s i r e d t a r g e t p o w e r s t a t e .
*
* @cpu_state : contains context save state (r0)
* 0 - No c o n t e x t l o s t
* 1 - CPUx L 1 a n d l o g i c l o s t : M P U S S C S W R
* 2 - CPUx L 1 a n d l o g i c l o s t + G I C l o s t : M P U S S O S W R
* 3 - CPUx L 1 a n d l o g i c l o s t + G I C + L 2 l o s t : M P U S S O F F
* @return: This function never returns for CPU OFF and DORMANT power states.
* Post W F I , C P U t r a n s i t i o n s t o D O R M A N T o r O F F p o w e r s t a t e a n d o n w a k e - u p
* from t h i s f o l l o w s a f u l l C P U r e s e t p a t h v i a R O M c o d e t o C P U r e s t o r e c o d e .
* The r e s t o r e f u n c t i o n p o i n t e r i s s t o r e d a t C P U x _ W A K E U P _ N S _ P A _ A D D R _ O F F S E T .
* It r e t u r n s t o t h e c a l l e r f o r C P U I N A C T I V E a n d O N p o w e r s t a t e s o r i n c a s e
* CPU f a i l e d t o t r a n s i t i o n t o t a r g e t e d O F F / D O R M A N T s t a t e .
2012-08-09 11:05:48 +04:00
*
* omap4 _ f i n i s h _ s u s p e n d ( ) c a l l s v7 _ f l u s h _ d c a c h e _ a l l ( ) w h i c h d o e s n ' t s a v e
* stack f r a m e a n d i t e x p e c t s t h e c a l l e r t o t a k e c a r e o f i t . H e n c e t h e e n t i r e
* stack f r a m e i s s a v e d t o a v o i d p o s s i b l e s t a c k c o r r u p t i o n .
2010-06-16 20:49:48 +04:00
* /
ENTRY( o m a p4 _ f i n i s h _ s u s p e n d )
2012-08-09 11:05:48 +04:00
stmfd s p ! , { r4 - r12 , l r }
2010-06-16 20:49:48 +04:00
cmp r0 , #0x0
beq d o _ W F I @ No lowpower state, jump to WFI
/ *
* Flush a l l d a t a f r o m t h e L 1 d a t a c a c h e b e f o r e d i s a b l i n g
* SCTLR. C b i t .
* /
bl o m a p4 _ g e t _ s a r _ r a m _ b a s e
ldr r9 , [ r0 , #O M A P _ T Y P E _ O F F S E T ]
cmp r9 , #0x1 @ Check for HS device
bne s k i p _ s e c u r e _ l 1 _ c l e a n
mov r0 , #S C U _ P M _ N O R M A L
mov r1 , #0xFF @ clean seucre L1
stmfd r13 ! , { r4 - r12 , r14 }
ldr r12 , =OMAP4_MON_SCU_PWR_INDEX
DO_ S M C
ldmfd r13 ! , { r4 - r12 , r14 }
skip_secure_l1_clean :
bl v7 _ f l u s h _ d c a c h e _ a l l
/ *
* Clear t h e S C T L R . C b i t t o p r e v e n t f u r t h e r d a t a c a c h e
* allocation. C l e a r i n g S C T L R . C w o u l d m a k e a l l t h e d a t a a c c e s s e s
* strongly o r d e r e d a n d w o u l d n o t h i t t h e c a c h e .
* /
mrc p15 , 0 , r0 , c1 , c0 , 0
bic r0 , r0 , #( 1 < < 2 ) @ Disable the C bit
mcr p15 , 0 , r0 , c1 , c0 , 0
isb
/ *
* Invalidate L 1 d a t a c a c h e . E v e n t h o u g h o n l y i n v a l i d a t e i s
* necessary e x p o r t e d f l u s h A P I i s u s e d h e r e . D o i n g c l e a n
* on a l r e a d y c l e a n c a c h e w o u l d b e a l m o s t N O P .
* /
bl v7 _ f l u s h _ d c a c h e _ a l l
/ *
* Switch t h e C P U f r o m S y m m e t r i c M u l t i p r o c e s s i n g ( S M P ) m o d e
* to A s y m m e t r i c M u l t i p r o c e s s i n g ( A M P ) m o d e b y p r o g r a m m i n g
* the S C U p o w e r s t a t u s t o D O R M A N T o r O F F m o d e .
* This e n a b l e s t h e C P U t o b e t a k e n o u t o f c o h e r e n c y b y
* preventing t h e C P U f r o m r e c e i v i n g c a c h e , T L B , o r B T B
* maintenance o p e r a t i o n s b r o a d c a s t b y o t h e r C P U s i n t h e c l u s t e r .
* /
bl o m a p4 _ g e t _ s a r _ r a m _ b a s e
mov r8 , r0
ldr r9 , [ r8 , #O M A P _ T Y P E _ O F F S E T ]
cmp r9 , #0x1 @ Check for HS device
bne s c u _ g p _ s e t
mrc p15 , 0 , r0 , c0 , c0 , 5 @ Read MPIDR
ands r0 , r0 , #0x0f
ldreq r0 , [ r8 , #S C U _ O F F S E T 0 ]
ldrne r0 , [ r8 , #S C U _ O F F S E T 1 ]
mov r1 , #0x00
stmfd r13 ! , { r4 - r12 , r14 }
ldr r12 , =OMAP4_MON_SCU_PWR_INDEX
DO_ S M C
ldmfd r13 ! , { r4 - r12 , r14 }
b s k i p _ s c u _ g p _ s e t
scu_gp_set :
mrc p15 , 0 , r0 , c0 , c0 , 5 @ Read MPIDR
ands r0 , r0 , #0x0f
ldreq r1 , [ r8 , #S C U _ O F F S E T 0 ]
ldrne r1 , [ r8 , #S C U _ O F F S E T 1 ]
bl o m a p4 _ g e t _ s c u _ b a s e
bl s c u _ p o w e r _ m o d e
skip_scu_gp_set :
mrc p15 , 0 , r0 , c1 , c1 , 2 @ Read NSACR data
tst r0 , #( 1 < < 1 8 )
mrcne p15 , 0 , r0 , c1 , c0 , 1
bicne r0 , r0 , #( 1 < < 6 ) @ Disable SMP bit
mcrne p15 , 0 , r0 , c1 , c0 , 1
isb
dsb
2011-01-09 00:29:09 +03:00
# ifdef C O N F I G _ C A C H E _ L 2 X 0
/ *
* Clean a n d i n v a l i d a t e t h e L 2 c a c h e .
* Common c a c h e - l 2 x0 . c f u n c t i o n s c a n ' t b e u s e d h e r e s i n c e i t
* uses s p i n l o c k s . W e a r e o u t o f c o h e r e n c y h e r e w i t h d a t a c a c h e
* disabled. T h e s p i n l o c k i m p l e m e n t a t i o n u s e s e x c l u s i v e l o a d / s t o r e
* instruction w h i c h c a n f a i l w i t h o u t d a t a c a c h e b e i n g e n a b l e d .
* OMAP4 h a r d w a r e d o e s n ' t s u p p o r t e x c l u s i v e m o n i t o r w h i c h c a n
* overcome e x c l u s i v e a c c e s s i s s u e . B e c a u s e o f t h i s , C P U c a n
* lead t o d e a d l o c k .
* /
bl o m a p4 _ g e t _ s a r _ r a m _ b a s e
mov r8 , r0
mrc p15 , 0 , r5 , c0 , c0 , 5 @ Read MPIDR
ands r5 , r5 , #0x0f
ldreq r0 , [ r8 , #L 2 X 0 _ S A V E _ O F F S E T 0 ] @ Retrieve L2 state from SAR
ldrne r0 , [ r8 , #L 2 X 0 _ S A V E _ O F F S E T 1 ] @ memory.
cmp r0 , #3
bne d o _ W F I
# ifdef C O N F I G _ P L 3 1 0 _ E R R A T A _ 7 2 7 9 1 5
mov r0 , #0x03
mov r12 , #O M A P 4 _ M O N _ L 2 X 0 _ D B G _ C T R L _ I N D E X
DO_ S M C
# endif
bl o m a p4 _ g e t _ l 2 c a c h e _ b a s e
mov r2 , r0
ldr r0 , =0xffff
str r0 , [ r2 , #L 2 X 0 _ C L E A N _ I N V _ W A Y ]
wait :
ldr r0 , [ r2 , #L 2 X 0 _ C L E A N _ I N V _ W A Y ]
ldr r1 , =0xffff
ands r0 , r0 , r1
bne w a i t
# ifdef C O N F I G _ P L 3 1 0 _ E R R A T A _ 7 2 7 9 1 5
mov r0 , #0x00
mov r12 , #O M A P 4 _ M O N _ L 2 X 0 _ D B G _ C T R L _ I N D E X
DO_ S M C
# endif
l2x_sync :
bl o m a p4 _ g e t _ l 2 c a c h e _ b a s e
mov r2 , r0
mov r0 , #0x0
str r0 , [ r2 , #L 2 X 0 _ C A C H E _ S Y N C ]
sync :
ldr r0 , [ r2 , #L 2 X 0 _ C A C H E _ S Y N C ]
ands r0 , r0 , #0x1
bne s y n c
# endif
2010-06-16 20:49:48 +04:00
do_WFI :
bl o m a p _ d o _ w f i
/ *
* CPU i s h e r e w h e n i t f a i l e d t o e n t e r O F F / D O R M A N T o r
* no l o w p o w e r s t a t e w a s a t t e m p t e d .
* /
mrc p15 , 0 , r0 , c1 , c0 , 0
tst r0 , #( 1 < < 2 ) @ Check C bit enabled?
orreq r0 , r0 , #( 1 < < 2 ) @ Enable the C bit
mcreq p15 , 0 , r0 , c1 , c0 , 0
isb
/ *
* Ensure t h e C P U p o w e r s t a t e i s s e t t o N O R M A L i n
* SCU p o w e r s t a t e s o t h a t C P U i s b a c k i n c o h e r e n c y .
* In n o n - c o h e r e n t m o d e C P U c a n l o c k - u p a n d l e a d t o
* system d e a d l o c k .
* /
mrc p15 , 0 , r0 , c1 , c0 , 1
tst r0 , #( 1 < < 6 ) @ Check SMP bit enabled?
orreq r0 , r0 , #( 1 < < 6 )
mcreq p15 , 0 , r0 , c1 , c0 , 1
isb
bl o m a p4 _ g e t _ s a r _ r a m _ b a s e
mov r8 , r0
ldr r9 , [ r8 , #O M A P _ T Y P E _ O F F S E T ]
cmp r9 , #0x1 @ Check for HS device
bne s c u _ g p _ c l e a r
mov r0 , #S C U _ P M _ N O R M A L
mov r1 , #0x00
stmfd r13 ! , { r4 - r12 , r14 }
ldr r12 , =OMAP4_MON_SCU_PWR_INDEX
DO_ S M C
ldmfd r13 ! , { r4 - r12 , r14 }
b s k i p _ s c u _ g p _ c l e a r
scu_gp_clear :
bl o m a p4 _ g e t _ s c u _ b a s e
mov r1 , #S C U _ P M _ N O R M A L
bl s c u _ p o w e r _ m o d e
skip_scu_gp_clear :
isb
dsb
2012-08-09 11:05:48 +04:00
ldmfd s p ! , { r4 - r12 , p c }
2010-06-16 20:49:48 +04:00
ENDPROC( o m a p4 _ f i n i s h _ s u s p e n d )
/ *
* = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* = = CPU r e s u m e e n t r y p o i n t = =
* = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*
* void o m a p4 _ c p u _ r e s u m e ( v o i d )
*
* ROM c o d e j u m p s t o t h i s f u n c t i o n w h i l e w a k i n g u p f r o m C P U
* OFF o r D O R M A N T s t a t e . P h y s i c a l a d d r e s s o f t h e f u n c t i o n i s
* stored i n t h e S A R R A M w h i l e e n t e r i n g t o O F F o r D O R M A N T m o d e .
* The r e s t o r e f u n c t i o n p o i n t e r i s s t o r e d a t C P U x _ W A K E U P _ N S _ P A _ A D D R _ O F F S E T .
* /
ENTRY( o m a p4 _ c p u _ r e s u m e )
/ *
* Configure A C T R L a n d e n a b l e N S S M P b i t a c c e s s o n C P U 1 o n H S d e v i c e .
* OMAP4 4 X X E M U / H S d e v i c e s - C P U 0 S M P b i t a c c e s s i s e n a b l e d i n P P A
* init a n d f o r C P U 1 , a s e c u r e P P A A P I p r o v i d e d . C P U 0 m u s t b e O N
* while e x e c u t i n g N S _ S M P A P I o n C P U 1 a n d P P A v e r s i o n m u s t b e 1 . 4 . 0 + .
* OMAP4 4 3 X G P d e v i c e s - S M P b i t i s n ' t a c c e s s i b l e .
* OMAP4 4 6 X G P d e v i c e s - S M P b i t a c c e s s i s e n a b l e d o n b o t h C P U s .
* /
ldr r8 , =OMAP44XX_SAR_RAM_BASE
ldr r9 , [ r8 , #O M A P _ T Y P E _ O F F S E T ]
cmp r9 , #0x1 @ Skip if GP device
bne s k i p _ n s _ s m p _ e n a b l e
mrc p15 , 0 , r0 , c0 , c0 , 5
ands r0 , r0 , #0x0f
beq s k i p _ n s _ s m p _ e n a b l e
ppa_actrl_retry :
mov r0 , #O M A P 4 _ P P A _ C P U _ A C T R L _ S M P _ I N D E X
adr r3 , p p a _ z e r o _ p a r a m s @ Pointer to parameters
mov r1 , #0x0 @ Process ID
mov r2 , #0x4 @ Flag
mov r6 , #0xff
mov r12 , #0x00 @ Secure Service ID
DO_ S M C
cmp r0 , #0x0 @ API returns 0 on success.
beq e n a b l e _ s m p _ b i t
b p p a _ a c t r l _ r e t r y
enable_smp_bit :
mrc p15 , 0 , r0 , c1 , c0 , 1
tst r0 , #( 1 < < 6 ) @ Check SMP bit enabled?
orreq r0 , r0 , #( 1 < < 6 )
mcreq p15 , 0 , r0 , c1 , c0 , 1
isb
skip_ns_smp_enable :
2011-01-09 00:29:09 +03:00
# ifdef C O N F I G _ C A C H E _ L 2 X 0
/ *
* Restore t h e L 2 A U X C T R L a n d e n a b l e t h e L 2 c a c h e .
* OMAP4 _ M O N _ L 2 X 0 _ A U X C T R L _ I N D E X = P r o g r a m t h e L 2 X 0 A U X C T R L
* OMAP4 _ M O N _ L 2 X 0 _ C T R L _ I N D E X = E n a b l e t h e L 2 u s i n g L 2 X 0 C T R L
* register r0 c o n t a i n s v a l u e t o b e p r o g r a m m e d .
* L2 c a c h e i s a l r e a d y i n v a l i d a t e b y R O M c o d e a s p a r t
* of M P U S S O F F w a k e u p p a t h .
* /
ldr r2 , =OMAP44XX_L2CACHE_BASE
ldr r0 , [ r2 , #L 2 X 0 _ C T R L ]
and r0 , #0x0f
cmp r0 , #1
beq s k i p _ l 2 e n @ Skip if already enabled
ldr r3 , =OMAP44XX_SAR_RAM_BASE
ldr r1 , [ r3 , #O M A P _ T Y P E _ O F F S E T ]
cmp r1 , #0x1 @ Check for HS device
bne s e t _ g p _ p o r
ldr r0 , =OMAP4_PPA_L2_POR_INDEX
ldr r1 , =OMAP44XX_SAR_RAM_BASE
ldr r4 , [ r1 , #L 2 X 0 _ P R E F E T C H _ C T R L _ O F F S E T ]
adr r3 , p p a _ p o r _ p a r a m s
str r4 , [ r3 , #0x04 ]
mov r1 , #0x0 @ Process ID
mov r2 , #0x4 @ Flag
mov r6 , #0xff
mov r12 , #0x00 @ Secure Service ID
DO_ S M C
b s e t _ a u x _ c t r l
set_gp_por :
ldr r1 , =OMAP44XX_SAR_RAM_BASE
ldr r0 , [ r1 , #L 2 X 0 _ P R E F E T C H _ C T R L _ O F F S E T ]
ldr r12 , =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH
DO_ S M C
set_aux_ctrl :
ldr r1 , =OMAP44XX_SAR_RAM_BASE
ldr r0 , [ r1 , #L 2 X 0 _ A U X C T R L _ O F F S E T ]
ldr r12 , =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL
DO_ S M C
mov r0 , #0x1
ldr r12 , =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache
DO_ S M C
skip_l2en :
# endif
2010-06-16 20:49:48 +04:00
b c p u _ r e s u m e @ Jump to generic resume
ENDPROC( o m a p4 _ c p u _ r e s u m e )
# endif
2011-06-26 05:04:31 +04:00
# ifndef C O N F I G _ O M A P 4 _ E R R A T A _ I 6 8 8
ENTRY( o m a p _ b u s _ s y n c )
mov p c , l r
ENDPROC( o m a p _ b u s _ s y n c )
# endif
2010-06-16 20:49:48 +04:00
ENTRY( o m a p _ d o _ w f i )
stmfd s p ! , { l r }
2011-06-26 05:04:31 +04:00
/* Drain interconnect write buffers. */
bl o m a p _ b u s _ s y n c
2010-06-16 20:49:48 +04:00
/ *
* Execute a n I S B i n s t r u c t i o n t o e n s u r e t h a t a l l o f t h e
* CP1 5 r e g i s t e r c h a n g e s h a v e b e e n c o m m i t t e d .
* /
isb
/ *
* Execute a b a r r i e r i n s t r u c t i o n t o e n s u r e t h a t a l l c a c h e ,
* TLB a n d b r a n c h p r e d i c t o r m a i n t e n a n c e o p e r a t i o n s i s s u e d
* by a n y C P U i n t h e c l u s t e r h a v e c o m p l e t e d .
* /
dsb
dmb
/ *
* Execute a W F I i n s t r u c t i o n a n d w a i t u n t i l t h e
* STANDBYWFI o u t p u t i s a s s e r t e d t o i n d i c a t e t h a t t h e
* CPU i s i n i d l e a n d l o w p o w e r s t a t e . C P U c a n s p e c u a l a t i v e l y
* prefetch t h e i n s t r u c t i o n s s o a d d N O P s a f t e r W F I . S i x t e e n
* NOPs a s p e r C o r t e x - A 9 p i p e l i n e .
* /
wfi @ Wait For Interrupt
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
ldmfd s p ! , { p c }
ENDPROC( o m a p _ d o _ w f i )