2009-05-28 10:56:16 -07:00
/ *
* ( C) C o p y r i g h t 2 0 0 7
* Texas I n s t r u m e n t s
* Karthik D a s u < k a r t h i k - d p @ti.com>
*
* ( C) C o p y r i g h t 2 0 0 4
* Texas I n s t r u m e n t s , < w w w . t i . c o m >
* Richard W o o d r u f f < r - w o o d r u f f2 @ti.com>
*
* 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 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 ; either version 2 of
* the L i c e n s e , o r ( a t 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 ,
* MA 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 >
2010-12-18 16:44:42 +01:00
# include < p l a t / s r a m . h >
2009-05-28 10:56:16 -07:00
# include < m a c h / i o . h >
2010-12-21 15:30:55 -07:00
# include " c m 2 x x x _ 3 x x x . h "
# include " p r m 2 x x x _ 3 x x x . h "
2009-05-28 10:56:16 -07:00
# include " s d r c . h "
2010-10-08 11:40:20 -06:00
# include " c o n t r o l . h "
2009-05-28 10:56:16 -07:00
2010-12-18 16:44:43 +01:00
/ *
* Registers a c c e s s d e f i n i t i o n s
* /
# define S D R C _ S C R A T C H P A D _ S E M _ O F F S 0 x c
# define S D R C _ S C R A T C H P A D _ S E M _ V O M A P 3 4 3 X _ S C R A T C H P A D _ R E G A D D R \
( SDRC_ S C R A T C H P A D _ S E M _ O F F S )
# define P M _ P R E P W S T S T _ C O R E _ P O M A P 3 4 3 0 _ P R M _ B A S E + C O R E _ M O D + \
OMAP3 4 3 0 _ P M _ P R E P W S T S T
2010-01-26 20:12:51 -07:00
# define P M _ P W S T C T R L _ M P U _ P O M A P 3 4 3 0 _ P R M _ B A S E + M P U _ M O D + O M A P 2 _ P M _ P W S T C T R L
2009-01-16 18:53:48 +02:00
# define C M _ I D L E S T 1 _ C O R E _ V O M A P 3 4 X X _ C M _ R E G A D D R ( C O R E _ M O D , C M _ I D L E S T 1 )
2010-12-20 14:05:04 -06:00
# define C M _ I D L E S T _ C K G E N _ V O M A P 3 4 X X _ C M _ R E G A D D R ( P L L _ M O D , C M _ I D L E S T )
2010-12-18 16:44:43 +01:00
# define S R A M _ B A S E _ P O M A P 3 _ S R A M _ P A
# define C O N T R O L _ S T A T O M A P 3 4 3 X _ C T R L _ B A S E + O M A P 3 4 3 X _ C O N T R O L _ S T A T U S
# define C O N T R O L _ M E M _ R T A _ C T R L ( O M A P 3 4 3 X _ C T R L _ B A S E + \
OMAP3 6 X X _ C O N T R O L _ M E M _ R T A _ C T R L )
/* Move this as correct place is available */
# define S C R A T C H P A D _ M E M _ O F F S 0 x31 0
# define S C R A T C H P A D _ B A S E _ P ( O M A P 3 4 3 X _ C T R L _ B A S E + \
OMAP3 4 3 X _ C O N T R O L _ M E M _ W K U P + \
SCRATCHPAD_ M E M _ O F F S )
2009-05-28 10:56:16 -07:00
# define S D R C _ P O W E R _ V O M A P 3 4 X X _ S D R C _ R E G A D D R ( S D R C _ P O W E R )
2008-10-13 17:58:50 +03:00
# define S D R C _ S Y S C O N F I G _ P ( O M A P 3 4 3 X _ S D R C _ B A S E + S D R C _ S Y S C O N F I G )
# define S D R C _ M R _ 0 _ P ( O M A P 3 4 3 X _ S D R C _ B A S E + S D R C _ M R _ 0 )
# define S D R C _ E M R 2 _ 0 _ P ( O M A P 3 4 3 X _ S D R C _ B A S E + S D R C _ E M R 2 _ 0 )
# define S D R C _ M A N U A L _ 0 _ P ( O M A P 3 4 3 X _ S D R C _ B A S E + S D R C _ M A N U A L _ 0 )
# define S D R C _ M R _ 1 _ P ( O M A P 3 4 3 X _ S D R C _ B A S E + S D R C _ M R _ 1 )
# define S D R C _ E M R 2 _ 1 _ P ( O M A P 3 4 3 X _ S D R C _ B A S E + S D R C _ E M R 2 _ 1 )
# define S D R C _ M A N U A L _ 1 _ P ( O M A P 3 4 3 X _ S D R C _ B A S E + S D R C _ M A N U A L _ 1 )
2009-01-16 18:53:48 +02:00
# define S D R C _ D L L A _ S T A T U S _ V O M A P 3 4 X X _ S D R C _ R E G A D D R ( S D R C _ D L L A _ S T A T U S )
# define S D R C _ D L L A _ C T R L _ V O M A P 3 4 X X _ S D R C _ R E G A D D R ( S D R C _ D L L A _ C T R L )
2009-05-28 10:56:16 -07:00
2010-12-18 16:44:41 +01:00
/ *
* API f u n c t i o n s
2010-12-18 16:44:45 +01:00
* /
/ *
* The " g e t _ * r e s t o r e _ p o i n t e r " f u n c t i o n s a r e u s e d t o p r o v i d e a
* physical r e s t o r e a d d r e s s w h e r e t h e R O M c o d e j u m p s w h i l e w a k i n g
* up f r o m M P U O F F / O S W R s t a t e .
* The r e s t o r e p o i n t e r i s s t o r e d i n t o t h e s c r a t c h p a d .
2010-12-18 16:44:41 +01:00
* /
2009-05-28 18:13:06 +05:30
2009-05-28 10:56:16 -07:00
.text
/* Function call to get the restore pointer for resume from OFF */
ENTRY( g e t _ r e s t o r e _ p o i n t e r )
2010-12-18 16:49:57 +01:00
stmfd s p ! , { l r } @ save registers on stack
2009-05-28 10:56:16 -07:00
adr r0 , r e s t o r e
2010-12-18 16:49:57 +01:00
ldmfd s p ! , { p c } @ restore regs and return
2009-05-28 10:56:16 -07:00
ENTRY( g e t _ r e s t o r e _ p o i n t e r _ s z )
2010-12-18 16:49:57 +01:00
.word . - get_ r e s t o r e _ p o i n t e r
2010-12-18 16:44:44 +01:00
2010-12-20 14:05:06 -06:00
.text
/* Function call to get the restore pointer for 3630 resume from OFF */
ENTRY( g e t _ o m a p36 3 0 _ r e s t o r e _ p o i n t e r )
2010-12-18 16:49:57 +01:00
stmfd s p ! , { l r } @ save registers on stack
2010-12-20 14:05:06 -06:00
adr r0 , r e s t o r e _ 3 6 3 0
2010-12-18 16:49:57 +01:00
ldmfd s p ! , { p c } @ restore regs and return
2010-12-20 14:05:06 -06:00
ENTRY( g e t _ o m a p36 3 0 _ r e s t o r e _ p o i n t e r _ s z )
2010-12-18 16:49:57 +01:00
.word . - get_ o m a p36 3 0 _ r e s t o r e _ p o i n t e r
2008-10-13 17:58:50 +03:00
2010-12-18 16:44:44 +01:00
.text
/* Function call to get the restore pointer for ES3 to resume from OFF */
ENTRY( g e t _ e s3 _ r e s t o r e _ p o i n t e r )
stmfd s p ! , { l r } @ save registers on stack
adr r0 , r e s t o r e _ e s3
ldmfd s p ! , { p c } @ restore regs and return
ENTRY( g e t _ e s3 _ r e s t o r e _ p o i n t e r _ s z )
.word . - get_ e s3 _ r e s t o r e _ p o i n t e r
2010-12-20 14:05:07 -06:00
.text
/ *
* L2 c a c h e n e e d s t o b e t o g g l e d f o r s t a b l e O F F m o d e f u n c t i o n a l i t y o n 3 6 3 0 .
2010-12-18 16:44:44 +01:00
* This f u n c t i o n s e t s u p a f l a g t h a t w i l l a l l o w f o r t h i s t o g g l i n g t o t a k e
2010-12-18 16:44:45 +01:00
* place o n 3 6 3 0 . H o p e f u l l y s o m e v e r s i o n i n t h e f u t u r e m a y n o t n e e d t h i s .
2010-12-20 14:05:07 -06:00
* /
ENTRY( e n a b l e _ o m a p36 3 0 _ t o g g l e _ l 2 _ o n _ r e s t o r e )
2010-12-18 16:49:57 +01:00
stmfd s p ! , { l r } @ save registers on stack
2010-12-20 14:05:07 -06:00
/* Setup so that we will disable and enable l2 */
mov r1 , #0x1
str r1 , l 2 d i s _ 3 6 3 0
2010-12-18 16:49:57 +01:00
ldmfd s p ! , { p c } @ restore regs and return
2010-12-20 14:05:07 -06:00
2010-12-18 16:49:57 +01:00
.text
2008-10-13 13:15:00 +03:00
/* Function to call rom code to save secure ram context */
ENTRY( s a v e _ s e c u r e _ r a m _ c o n t e x t )
stmfd s p ! , { r1 - r12 , l r } @ save registers on stack
adr r3 , a p i _ p a r a m s @ r3 points to parameters
str r0 , [ r3 ,#0x4 ] @ r0 has sdram address
ldr r12 , h i g h _ m a s k
and r3 , r3 , r12
ldr r12 , s r a m _ p h y _ a d d r _ m a s k
orr r3 , r3 , r12
mov r0 , #25 @ set service ID for PPA
mov r12 , r0 @ copy secure service ID in r12
mov r1 , #0 @ set task id for ROM code in r1
2009-03-26 15:59:00 +02:00
mov r2 , #4 @ set some flags in r2, r6
2008-10-13 13:15:00 +03:00
mov r6 , #0xff
mcr p15 , 0 , r0 , c7 , c10 , 4 @ data write barrier
mcr p15 , 0 , r0 , c7 , c10 , 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
nop
nop
nop
nop
ldmfd s p ! , { r1 - r12 , p c }
sram_phy_addr_mask :
.word SRAM_BASE_P
high_mask :
.word 0xffff
api_params :
.word 0 x4 , 0 x0 , 0 x0 , 0 x1 , 0 x1
ENTRY( s a v e _ s e c u r e _ r a m _ c o n t e x t _ s z )
.word . - save_ s e c u r e _ r a m _ c o n t e x t
2010-12-18 16:44:45 +01:00
/ *
* = = = = = = = = = = = = = = = = = = = = = =
* = = Idle e n t r y p o i n t = =
* = = = = = = = = = = = = = = = = = = = = = =
* /
2009-05-28 10:56:16 -07:00
/ *
* Forces O M A P i n t o i d l e s t a t e
*
2010-12-18 16:44:45 +01:00
* omap3 4 x x _ c p u _ s u s p e n d ( ) - T h i s b i t o f c o d e s a v e s t h e C P U c o n t e x t i f n e e d e d
* and e x e c u t e s t h e W F I i n s t r u c t i o n . 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
* 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 s .
*
2009-05-28 10:56:16 -07:00
*
2010-12-18 16:44:45 +01:00
* Notes :
2010-12-18 16:49:57 +01:00
* - this c o d e g e t s c o p i e d t o i n t e r n a l S R A M a t b o o t a n d a f t e r w a k e - u p
* from O F F m o d e . T h e e x e c u t i o n p o i n t e r i n S R A M i s _ o m a p _ s r a m _ i d l e .
2010-12-18 16:44:45 +01:00
* - when t h e O M A P w a k e s u p i t c o n t i n u e s a t d i f f e r e n t e x e c u t i o n p o i n t s
* depending o n t h e l o w p o w e r m o d e ( n o n - O F F v s O F F m o d e s ) ,
* cf. ' R e s u m e p a t h f o r x x x m o d e ' c o m m e n t s .
2009-05-28 10:56:16 -07:00
* /
ENTRY( o m a p34 x x _ c p u _ s u s p e n d )
2010-12-18 16:49:57 +01:00
stmfd s p ! , { r0 - r12 , l r } @ save registers on stack
2010-12-18 16:44:41 +01:00
2010-12-18 16:44:45 +01:00
/ *
* r0 c o n t a i n s r e s t o r e p o i n t e r i n s d r a m
* r1 c o n t a i n s i n f o r m a t i o n a b o u t s a v i n g c o n t e x t :
* 0 - No c o n t e x t l o s t
* 1 - Only L 1 a n d l o g i c l o s t
* 2 - Only L 2 l o s t
* 3 - Both L 1 a n d L 2 l o s t
* /
2009-05-28 10:56:16 -07:00
2010-12-18 16:44:45 +01:00
/* Directly jump to WFI is the context save is not required */
2009-05-28 10:56:16 -07:00
cmp r1 , #0x0
2010-12-18 16:44:45 +01:00
beq o m a p3 _ d o _ w f i
/* Otherwise fall through to the save context code */
save_context_wfi :
mov r8 , r0 @ Store SDRAM address in r8
mrc p15 , 0 , r5 , c1 , c0 , 1 @ Read Auxiliary Control Register
mov r4 , #0x1 @ Number of parameters for restore call
stmia r8 ! , { r4 - r5 } @ Push parameters for restore call
mrc p15 , 1 , r5 , c9 , c0 , 2 @ Read L2 AUX ctrl register
stmia r8 ! , { r4 - r5 } @ Push parameters for restore call
/* Check what that target sleep state is from r1 */
cmp r1 , #0x2 @ Only L2 lost, no need to save context
beq c l e a n _ c a c h e s
l1_logic_lost :
/* Store sp and spsr to SDRAM */
mov r4 , s p
mrs r5 , s p s r
mov r6 , l r
stmia r8 ! , { r4 - r6 }
/* Save all ARM registers */
/* Coprocessor access control register */
mrc p15 , 0 , r6 , c1 , c0 , 2
stmia r8 ! , { r6 }
/* TTBR0, TTBR1 and Translation table base control */
mrc p15 , 0 , r4 , c2 , c0 , 0
mrc p15 , 0 , r5 , c2 , c0 , 1
mrc p15 , 0 , r6 , c2 , c0 , 2
stmia r8 ! , { r4 - r6 }
/ *
* Domain a c c e s s c o n t r o l r e g i s t e r , d a t a f a u l t s t a t u s r e g i s t e r ,
* and i n s t r u c t i o n f a u l t s t a t u s r e g i s t e r
* /
mrc p15 , 0 , r4 , c3 , c0 , 0
mrc p15 , 0 , r5 , c5 , c0 , 0
mrc p15 , 0 , r6 , c5 , c0 , 1
stmia r8 ! , { r4 - r6 }
/ *
* Data a u x f a u l t s t a t u s r e g i s t e r , i n s t r u c t i o n a u x f a u l t s t a t u s ,
* data f a u l t a d d r e s s r e g i s t e r a n d i n s t r u c t i o n f a u l t a d d r e s s r e g i s t e r
* /
mrc p15 , 0 , r4 , c5 , c1 , 0
mrc p15 , 0 , r5 , c5 , c1 , 1
mrc p15 , 0 , r6 , c6 , c0 , 0
mrc p15 , 0 , r7 , c6 , c0 , 2
stmia r8 ! , { r4 - r7 }
/ *
* user r / w t h r e a d a n d p r o c e s s I D , u s e r r / o t h r e a d a n d p r o c e s s I D ,
* priv o n l y t h r e a d a n d p r o c e s s I D , c a c h e s i z e s e l e c t i o n
* /
mrc p15 , 0 , r4 , c13 , c0 , 2
mrc p15 , 0 , r5 , c13 , c0 , 3
mrc p15 , 0 , r6 , c13 , c0 , 4
mrc p15 , 2 , r7 , c0 , c0 , 0
stmia r8 ! , { r4 - r7 }
/* Data TLB lockdown, instruction TLB lockdown registers */
mrc p15 , 0 , r5 , c10 , c0 , 0
mrc p15 , 0 , r6 , c10 , c0 , 1
stmia r8 ! , { r5 - r6 }
/* Secure or non secure vector base address, FCSE PID, Context PID*/
mrc p15 , 0 , r4 , c12 , c0 , 0
mrc p15 , 0 , r5 , c13 , c0 , 0
mrc p15 , 0 , r6 , c13 , c0 , 1
stmia r8 ! , { r4 - r6 }
/* Primary remap, normal remap registers */
mrc p15 , 0 , r4 , c10 , c2 , 0
mrc p15 , 0 , r5 , c10 , c2 , 1
stmia r8 ! ,{ r4 - r5 }
/* Store current cpsr*/
mrs r2 , c p s r
stmia r8 ! , { r2 }
mrc p15 , 0 , r4 , c1 , c0 , 0
/* save control register */
stmia r8 ! , { r4 }
clean_caches :
/ *
* Clean D a t a o r u n i f i e d c a c h e t o P O U
* How t o i n v a l i d a t e o n l y L 1 c a c h e ? ? ? ? - #F I X _ M E #
* mcr p15 , 0 , r11 , c7 , c11 , 1
* /
cmp r1 , #0x1 @ Check whether L2 inval is required
beq o m a p3 _ d o _ w f i
clean_l2 :
/ *
* jump o u t t o k e r n e l f l u s h r o u t i n e
* - reuse t h a t c o d e i s b e t t e r
* - it e x e c u t e s i n a c a c h e d s p a c e s o i s f a s t e r t h a n r e f e t c h p e r - b l o c k
* - should b e f a s t e r a n d w i l l c h a n g e w i t h k e r n e l
* - ' might' h a v e t o c o p y a d d r e s s , l o a d a n d j u m p t o i t
* /
2010-12-18 16:49:57 +01:00
ldr r1 , k e r n e l _ f l u s h
mov l r , p c
bx r1
2010-12-18 16:44:45 +01:00
omap3_do_wfi :
ldr r4 , s d r c _ p o w e r @ read the SDRC_POWER register
ldr r5 , [ r4 ] @ read the contents of SDRC_POWER
orr r5 , r5 , #0x40 @ enable self refresh on idle req
str r5 , [ r4 ] @ write back to SDRC_POWER register
2009-05-28 10:56:16 -07:00
/* Data memory barrier and Data sync barrier */
mov r1 , #0
mcr p15 , 0 , r1 , c7 , c10 , 4
mcr p15 , 0 , r1 , c7 , c10 , 5
2010-12-18 16:44:45 +01:00
/ *
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* = = WFI i n s t r u c t i o n = > E n t e r i d l e = =
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* /
2009-05-28 10:56:16 -07:00
wfi @ wait for interrupt
2010-12-18 16:44:45 +01:00
/ *
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* = = Resume p a t h f o r n o n - O F F m o d e s = =
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* /
2009-05-28 10:56:16 -07:00
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
2009-01-16 18:53:48 +02:00
bl w a i t _ s d r c _ o k
2009-05-28 10:56:16 -07:00
2010-12-18 16:44:45 +01:00
/ *
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* = = Exit p o i n t f r o m n o n - O F F m o d e s = =
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* /
ldmfd s p ! , { r0 - r12 , p c } @ restore regs and return
/ *
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* = = Resume p a t h f o r O F F m o d e = =
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* /
/ *
* The r e s t o r e _ * f u n c t i o n s a r e c a l l e d b y t h e R O M c o d e
* when b a c k f r o m W F I i n O F F m o d e .
* Cf. t h e g e t _ * r e s t o r e _ p o i n t e r f u n c t i o n s .
*
* restore_es3 : applies t o 3 4 x x > = E S 3 . 0
* restore_3630 : applies t o 3 6 x x
* restore : common c o d e f o r 3 x x x
* /
2008-10-13 17:58:50 +03:00
restore_es3 :
ldr r5 , p m _ p r e p w s t s t _ c o r e _ p
ldr r4 , [ r5 ]
and r4 , r4 , #0x3
cmp r4 , #0x0 @ Check if previous power state of CORE is OFF
bne r e s t o r e
adr r0 , e s3 _ s d r c _ f i x
ldr r1 , s r a m _ b a s e
ldr r2 , e s3 _ s d r c _ f i x _ s z
mov r2 , r2 , r o r #2
copy_to_sram :
ldmia r0 ! , { r3 } @ val = *src
stmia r1 ! , { r3 } @ *dst = val
subs r2 , r2 , #0x1 @ num_words--
bne c o p y _ t o _ s r a m
ldr r1 , s r a m _ b a s e
blx r1
2010-12-20 14:05:06 -06:00
b r e s t o r e
restore_3630 :
ldr r1 , p m _ p r e p w s t s t _ c o r e _ p
ldr r2 , [ r1 ]
and r2 , r2 , #0x3
cmp r2 , #0x0 @ Check if previous power state of CORE is OFF
bne r e s t o r e
/* Disable RTA before giving control */
ldr r1 , c o n t r o l _ m e m _ r t a
mov r2 , #O M A P 36 X X _ R T A _ D I S A B L E
str r2 , [ r1 ]
2010-12-18 16:44:45 +01:00
/* Fall through to common code for the remaining logic */
2009-05-28 10:56:16 -07:00
restore :
2010-12-18 16:49:57 +01:00
/ *
2010-12-18 16:44:45 +01:00
* Check w h a t w a s t h e r e a s o n f o r m p u r e s e t a n d s t o r e t h e r e a s o n i n r9 :
* 0 - No c o n t e x t l o s t
2010-12-18 16:49:57 +01:00
* 1 - Only L 1 a n d l o g i c l o s t
* 2 - Only L 2 l o s t - I n t h i s c a s e , w e w o n t b e h e r e
* 3 - Both L 1 a n d L 2 l o s t
2010-12-18 16:44:45 +01:00
* /
2010-12-18 16:49:57 +01:00
ldr r1 , p m _ p w s t c t r l _ m p u
2009-05-28 10:56:16 -07:00
ldr r2 , [ r1 ]
2010-12-18 16:49:57 +01:00
and r2 , r2 , #0x3
cmp r2 , #0x0 @ Check if target power state was OFF or RET
moveq r9 , #0x3 @ MPU OFF => L1 and L2 lost
2009-05-28 10:56:16 -07:00
movne r9 , #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
bne l o g i c _ l 1 _ r e s t o r e
2010-12-20 14:05:07 -06:00
ldr r0 , l 2 d i s _ 3 6 3 0
cmp r0 , #0x1 @ should we disable L2 on 3630?
bne s k i p l 2 d i s
mrc p15 , 0 , r0 , c1 , c0 , 1
bic r0 , r0 , #2 @ disable L2 cache
mcr p15 , 0 , r0 , c1 , c0 , 1
skipl2dis :
2008-10-13 13:15:00 +03:00
ldr r0 , c o n t r o l _ s t a t
ldr r1 , [ r0 ]
and r1 , #0x700
cmp r1 , #0x300
beq l 2 _ i n v _ g p
2010-12-18 16:49:57 +01:00
mov r0 , #40 @ set service ID for PPA
mov r12 , r0 @ copy secure Service ID in r12
mov r1 , #0 @ set task id for ROM code in r1
mov r2 , #4 @ set some flags in r2, r6
2008-10-13 13:15:00 +03:00
mov r6 , #0xff
adr r3 , l 2 _ i n v _ a p i _ p a r a m s @ r3 points to dummy parameters
mcr p15 , 0 , r0 , c7 , c10 , 4 @ data write barrier
mcr p15 , 0 , r0 , c7 , c10 , 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
/* Write to Aux control register to set some bits */
2010-12-18 16:49:57 +01:00
mov r0 , #42 @ set service ID for PPA
mov r12 , r0 @ copy secure Service ID in r12
mov r1 , #0 @ set task id for ROM code in r1
mov r2 , #4 @ set some flags in r2, r6
2008-10-13 13:15:00 +03:00
mov r6 , #0xff
2009-11-12 12:07:20 +02:00
ldr r4 , s c r a t c h p a d _ b a s e
2010-12-18 16:49:57 +01:00
ldr r3 , [ r4 , #0xBC ] @ r3 points to parameters
2008-10-13 13:15:00 +03:00
mcr p15 , 0 , r0 , c7 , c10 , 4 @ data write barrier
mcr p15 , 0 , r0 , c7 , c10 , 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
2009-11-12 12:07:22 +02:00
# ifdef C O N F I G _ O M A P 3 _ L 2 _ A U X _ S E C U R E _ S A V E _ R E S T O R E
/* Restore L2 aux control register */
2010-12-18 16:49:57 +01:00
@ set service ID for PPA
2009-11-12 12:07:22 +02:00
mov r0 , #C O N F I G _ O M A P 3 _ L 2 _ A U X _ S E C U R E _ S E R V I C E _ S E T _ I D
2010-12-18 16:49:57 +01:00
mov r12 , r0 @ copy service ID in r12
mov r1 , #0 @ set task ID for ROM code in r1
mov r2 , #4 @ set some flags in r2, r6
2009-11-12 12:07:22 +02:00
mov r6 , #0xff
ldr r4 , s c r a t c h p a d _ b a s e
ldr r3 , [ r4 , #0xBC ]
2010-12-18 16:49:57 +01:00
adds r3 , r3 , #8 @ r3 points to parameters
2009-11-12 12:07:22 +02:00
mcr p15 , 0 , r0 , c7 , c10 , 4 @ data write barrier
mcr p15 , 0 , r0 , c7 , c10 , 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
# endif
2008-10-13 13:15:00 +03:00
b l o g i c _ l 1 _ r e s t o r e
2010-12-18 16:49:57 +01:00
2008-10-13 13:15:00 +03:00
l2_inv_api_params :
2010-12-18 16:49:57 +01:00
.word 0 x1 , 0 x00
2008-10-13 13:15:00 +03:00
l2_inv_gp :
2009-05-28 10:56:16 -07:00
/* Execute smi to invalidate L2 cache */
2010-12-18 16:49:57 +01:00
mov r12 , #0x1 @ set up to invalidate L2
.word 0xE1600070 @ Call SMI monitor (smieq)
2008-10-13 13:15:00 +03:00
/* Write to Aux control register to set some bits */
2009-11-12 12:07:20 +02:00
ldr r4 , s c r a t c h p a d _ b a s e
ldr r3 , [ r4 ,#0xBC ]
ldr r0 , [ r3 ,#4 ]
2008-10-13 13:15:00 +03:00
mov r12 , #0x3
2010-12-18 16:49:57 +01:00
.word 0xE1600070 @ Call SMI monitor (smieq)
2009-11-12 12:07:22 +02:00
ldr r4 , s c r a t c h p a d _ b a s e
ldr r3 , [ r4 ,#0xBC ]
ldr r0 , [ r3 ,#12 ]
mov r12 , #0x2
2010-12-18 16:49:57 +01:00
.word 0xE1600070 @ Call SMI monitor (smieq)
2009-05-28 10:56:16 -07:00
logic_l1_restore :
2010-12-20 14:05:07 -06:00
ldr r1 , l 2 d i s _ 3 6 3 0
2010-12-18 16:49:57 +01:00
cmp r1 , #0x1 @ Test if L2 re-enable needed on 3630
2010-12-20 14:05:07 -06:00
bne s k i p l 2 r e e n
mrc p15 , 0 , r1 , c1 , c0 , 1
2010-12-18 16:49:57 +01:00
orr r1 , r1 , #2 @ re-enable L2 cache
2010-12-20 14:05:07 -06:00
mcr p15 , 0 , r1 , c1 , c0 , 1
skipl2reen :
2009-05-28 10:56:16 -07:00
mov r1 , #0
2010-12-18 16:49:57 +01:00
/ *
* Invalidate a l l i n s t r u c t i o n c a c h e s t o P o U
* and f l u s h b r a n c h t a r g e t c a c h e
* /
2009-05-28 10:56:16 -07:00
mcr p15 , 0 , r1 , c7 , c5 , 0
ldr r4 , s c r a t c h p a d _ b a s e
ldr r3 , [ r4 ,#0xBC ]
2009-11-12 12:07:22 +02:00
adds r3 , r3 , #16
2009-05-28 10:56:16 -07:00
ldmia r3 ! , { r4 - r6 }
mov s p , r4
msr s p s r _ c x s f , r5
mov l r , r6
ldmia r3 ! , { r4 - r9 }
/* Coprocessor access Control Register */
mcr p15 , 0 , r4 , c1 , c0 , 2
/* TTBR0 */
MCR p15 , 0 , r5 , c2 , c0 , 0
/* TTBR1 */
MCR p15 , 0 , r6 , c2 , c0 , 1
/* Translation table base control register */
MCR p15 , 0 , r7 , c2 , c0 , 2
2010-12-18 16:49:57 +01:00
/* Domain access Control Register */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r8 , c3 , c0 , 0
2010-12-18 16:49:57 +01:00
/* Data fault status Register */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r9 , c5 , c0 , 0
2010-12-18 16:49:57 +01:00
ldmia r3 ! ,{ r4 - r8 }
/* Instruction fault status Register */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r4 , c5 , c0 , 1
2010-12-18 16:49:57 +01:00
/* Data Auxiliary Fault Status Register */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r5 , c5 , c1 , 0
2010-12-18 16:49:57 +01:00
/* Instruction Auxiliary Fault Status Register*/
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r6 , c5 , c1 , 1
2010-12-18 16:49:57 +01:00
/* Data Fault Address Register */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r7 , c6 , c0 , 0
2010-12-18 16:49:57 +01:00
/* Instruction Fault Address Register*/
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r8 , c6 , c0 , 2
2010-12-18 16:49:57 +01:00
ldmia r3 ! ,{ r4 - r7 }
2009-05-28 10:56:16 -07:00
2010-12-18 16:49:57 +01:00
/* User r/w thread and process ID */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r4 , c13 , c0 , 2
2010-12-18 16:49:57 +01:00
/* User ro thread and process ID */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r5 , c13 , c0 , 3
2010-12-18 16:49:57 +01:00
/* Privileged only thread and process ID */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r6 , c13 , c0 , 4
2010-12-18 16:49:57 +01:00
/* Cache size selection */
2009-05-28 10:56:16 -07:00
MCR p15 , 2 , r7 , c0 , c0 , 0
2010-12-18 16:49:57 +01:00
ldmia r3 ! ,{ r4 - r8 }
2009-05-28 10:56:16 -07:00
/* Data TLB lockdown registers */
MCR p15 , 0 , r4 , c10 , c0 , 0
/* Instruction TLB lockdown registers */
MCR p15 , 0 , r5 , c10 , c0 , 1
/* Secure or Nonsecure Vector Base Address */
MCR p15 , 0 , r6 , c12 , c0 , 0
/* FCSE PID */
MCR p15 , 0 , r7 , c13 , c0 , 0
/* Context PID */
MCR p15 , 0 , r8 , c13 , c0 , 1
2010-12-18 16:49:57 +01:00
ldmia r3 ! ,{ r4 - r5 }
/* Primary memory remap register */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r4 , c10 , c2 , 0
2010-12-18 16:49:57 +01:00
/* Normal memory remap register */
2009-05-28 10:56:16 -07:00
MCR p15 , 0 , r5 , c10 , c2 , 1
/* Restore cpsr */
2010-12-18 16:49:57 +01:00
ldmia r3 ! ,{ r4 } @ load CPSR from SDRAM
msr c p s r , r4 @ store cpsr
2009-05-28 10:56:16 -07:00
/* Enabling MMU here */
2010-12-18 16:49:57 +01:00
mrc p15 , 0 , r7 , c2 , c0 , 2 @ Read TTBRControl
/* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */
2009-05-28 10:56:16 -07:00
and r7 , #0x7
cmp r7 , #0x0
beq u s e t t b r0
ttbr_error :
2010-12-18 16:49:57 +01:00
/ *
* More w o r k n e e d s t o b e d o n e t o s u p p o r t N [ 0 : 2 ] v a l u e o t h e r t h a n 0
* So l o o p i n g h e r e s o t h a t t h e e r r o r c a n b e d e t e c t e d
* /
2009-05-28 10:56:16 -07:00
b t t b r _ e r r o r
usettbr0 :
mrc p15 , 0 , r2 , c2 , c0 , 0
ldr r5 , t t b r b i t _ m a s k
and r2 , r5
mov r4 , p c
ldr r5 , t a b l e _ i n d e x _ m a s k
2010-12-18 16:49:57 +01:00
and r4 , r5 @ r4 = 31 to 20 bits of pc
2009-05-28 10:56:16 -07:00
/* Extract the value to be written to table entry */
ldr r1 , t a b l e _ e n t r y
2010-12-18 16:49:57 +01:00
/* r1 has the value to be written to table entry*/
add r1 , r1 , r4
2009-05-28 10:56:16 -07:00
/* Getting the address of table entry to modify */
lsr r4 , #18
2010-12-18 16:49:57 +01:00
/* r2 has the location which needs to be modified */
add r2 , r4
2009-05-28 10:56:16 -07:00
/* Storing previous entry of location being modified */
ldr r5 , s c r a t c h p a d _ b a s e
ldr r4 , [ r2 ]
str r4 , [ r5 , #0xC0 ]
/* Modify the table entry */
str r1 , [ r2 ]
2010-12-18 16:49:57 +01:00
/ *
* Storing a d d r e s s o f e n t r y b e i n g m o d i f i e d
* - will b e r e s t o r e d a f t e r e n a b l i n g M M U
* /
2009-05-28 10:56:16 -07:00
ldr r5 , s c r a t c h p a d _ b a s e
str r2 , [ r5 , #0xC4 ]
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c5 , 4 @ Flush prefetch buffer
mcr p15 , 0 , r0 , c7 , c5 , 6 @ Invalidate branch predictor array
mcr p15 , 0 , r0 , c8 , c5 , 0 @ Invalidate instruction TLB
mcr p15 , 0 , r0 , c8 , c6 , 0 @ Invalidate data TLB
2010-12-18 16:49:57 +01:00
/ *
* Restore c o n t r o l r e g i s t e r . T h i s e n a b l e s t h e M M U .
* The c a c h e s a n d p r e d i c t i o n a r e n o t e n a b l e d h e r e , t h e y
* will b e e n a b l e d a f t e r r e s t o r i n g t h e M M U t a b l e e n t r y .
* /
2009-05-28 10:56:16 -07:00
ldmia r3 ! , { r4 }
/* Store previous value of control register in scratchpad */
str r4 , [ r5 , #0xC8 ]
ldr r2 , c a c h e _ p r e d _ d i s a b l e _ m a s k
and r4 , r2
mcr p15 , 0 , r4 , c1 , c0 , 0
2010-12-18 16:44:45 +01:00
/ *
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* = = Exit p o i n t f r o m O F F m o d e = =
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* /
2010-12-18 16:49:57 +01:00
ldmfd s p ! , { r0 - r12 , p c } @ restore regs and return
2009-05-28 10:56:16 -07:00
2010-12-18 16:44:44 +01:00
/ *
* Internal f u n c t i o n s
* /
2010-12-18 16:44:46 +01:00
/* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */
2010-12-18 16:44:44 +01:00
.text
ENTRY( e s3 _ s d r c _ f i x )
ldr r4 , s d r c _ s y s c f g @ get config addr
ldr r5 , [ r4 ] @ get value
tst r5 , #0x100 @ is part access blocked
it e q
biceq r5 , r5 , #0x100 @ clear bit if set
str r5 , [ r4 ] @ write back change
ldr r4 , s d r c _ m r _ 0 @ get config addr
ldr r5 , [ r4 ] @ get value
str r5 , [ r4 ] @ write back change
ldr r4 , s d r c _ e m r2 _ 0 @ get config addr
ldr r5 , [ r4 ] @ get value
str r5 , [ r4 ] @ write back change
ldr r4 , s d r c _ m a n u a l _ 0 @ get config addr
mov r5 , #0x2 @ autorefresh command
str r5 , [ r4 ] @ kick off refreshes
ldr r4 , s d r c _ m r _ 1 @ get config addr
ldr r5 , [ r4 ] @ get value
str r5 , [ r4 ] @ write back change
ldr r4 , s d r c _ e m r2 _ 1 @ get config addr
ldr r5 , [ r4 ] @ get value
str r5 , [ r4 ] @ write back change
ldr r4 , s d r c _ m a n u a l _ 1 @ get config addr
mov r5 , #0x2 @ autorefresh command
str r5 , [ r4 ] @ kick off refreshes
bx l r
sdrc_syscfg :
.word SDRC_SYSCONFIG_P
sdrc_mr_0 :
.word SDRC_MR_0_P
sdrc_emr2_0 :
.word SDRC_EMR2_0_P
sdrc_manual_0 :
.word SDRC_MANUAL_0_P
sdrc_mr_1 :
.word SDRC_MR_1_P
sdrc_emr2_1 :
.word SDRC_EMR2_1_P
sdrc_manual_1 :
.word SDRC_MANUAL_1_P
ENTRY( e s3 _ s d r c _ f i x _ s z )
.word . - es3 _ s d r c _ f i x
2010-12-18 16:44:46 +01:00
/ *
* This f u n c t i o n i m p l e m e n t s t h e e r r a t u m I D i 5 8 1 W A :
* SDRC s t a t e r e s t o r e b e f o r e a c c e s s i n g t h e S D R A M
*
* Only u s e d a t r e t u r n f r o m n o n - O F F m o d e . F o r O F F
* mode t h e R O M c o d e c o n f i g u r e s t h e S D R C a n d
* the D P L L b e f o r e c a l l i n g t h e r e s t o r e c o d e d i r e c t l y
* from D D R .
* /
2009-01-16 18:53:48 +02:00
/* Make sure SDRC accesses are ok */
wait_sdrc_ok :
2010-12-20 14:05:04 -06:00
2010-12-18 16:49:57 +01:00
/* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */
2010-12-20 14:05:04 -06:00
ldr r4 , c m _ i d l e s t _ c k g e n
wait_dpll3_lock :
ldr r5 , [ r4 ]
tst r5 , #1
beq w a i t _ d p l l 3 _ l o c k
2010-12-18 16:49:57 +01:00
ldr r4 , c m _ i d l e s t 1 _ c o r e
2010-12-20 14:05:04 -06:00
wait_sdrc_ready :
2010-12-18 16:49:57 +01:00
ldr r5 , [ r4 ]
tst r5 , #0x2
bne w a i t _ s d r c _ r e a d y
2010-12-20 14:05:04 -06:00
/* allow DLL powerdown upon hw idle req */
2010-12-18 16:49:57 +01:00
ldr r4 , s d r c _ p o w e r
ldr r5 , [ r4 ]
bic r5 , r5 , #0x40
str r5 , [ r4 ]
2010-12-20 14:05:04 -06:00
2010-12-18 16:49:57 +01:00
is_dll_in_lock_mode :
/* Is dll in lock mode? */
ldr r4 , s d r c _ d l l a _ c t r l
ldr r5 , [ r4 ]
tst r5 , #0x4
bxne l r @ Return if locked
/* wait till dll locks */
2010-12-20 14:05:04 -06:00
wait_dll_lock_timed :
ldr r4 , w a i t _ d l l _ l o c k _ c o u n t e r
add r4 , r4 , #1
str r4 , w a i t _ d l l _ l o c k _ c o u n t e r
ldr r4 , s d r c _ d l l a _ s t a t u s
2010-12-18 16:49:57 +01:00
/* Wait 20uS for lock */
mov r6 , #8
2010-12-20 14:05:04 -06:00
wait_dll_lock :
subs r6 , r6 , #0x1
beq k i c k _ d l l
2010-12-18 16:49:57 +01:00
ldr r5 , [ r4 ]
and r5 , r5 , #0x4
cmp r5 , #0x4
bne w a i t _ d l l _ l o c k
bx l r @ Return when locked
2009-05-28 10:56:16 -07:00
2010-12-20 14:05:04 -06:00
/* disable/reenable DLL if not locked */
kick_dll :
ldr r4 , s d r c _ d l l a _ c t r l
ldr r5 , [ r4 ]
mov r6 , r5
2010-12-18 16:49:57 +01:00
bic r6 , #( 1 < < 3 ) @ disable dll
2010-12-20 14:05:04 -06:00
str r6 , [ r4 ]
dsb
2010-12-18 16:49:57 +01:00
orr r6 , r6 , #( 1 < < 3 ) @ enable dll
2010-12-20 14:05:04 -06:00
str r6 , [ r4 ]
dsb
ldr r4 , k i c k _ c o u n t e r
add r4 , r4 , #1
str r4 , k i c k _ c o u n t e r
b w a i t _ d l l _ l o c k _ t i m e d
2009-01-16 18:53:48 +02:00
cm_idlest1_core :
.word CM_IDLEST1_CORE_V
2010-12-20 14:05:04 -06:00
cm_idlest_ckgen :
.word CM_IDLEST_CKGEN_V
2009-01-16 18:53:48 +02:00
sdrc_dlla_status :
.word SDRC_DLLA_STATUS_V
sdrc_dlla_ctrl :
.word SDRC_DLLA_CTRL_V
2008-10-13 17:58:50 +03:00
pm_prepwstst_core_p :
.word PM_PREPWSTST_CORE_P
2009-05-28 10:56:16 -07:00
pm_pwstctrl_mpu :
.word PM_PWSTCTRL_MPU_P
scratchpad_base :
.word SCRATCHPAD_BASE_P
2008-10-13 17:58:50 +03:00
sram_base :
.word SRAM_BASE_P + 0 x8 0 0 0
2009-05-28 10:56:16 -07:00
sdrc_power :
2010-12-18 16:49:57 +01:00
.word SDRC_POWER_V
2009-05-28 10:56:16 -07:00
ttbrbit_mask :
.word 0xFFFFC000
table_index_mask :
.word 0xFFF00000
table_entry :
.word 0x00000C02
cache_pred_disable_mask :
.word 0xFFFFE7FB
2008-10-13 13:15:00 +03:00
control_stat :
.word CONTROL_STAT
2010-12-20 14:05:06 -06:00
control_mem_rta :
.word CONTROL_MEM_RTA_CTRL
2010-12-20 14:05:03 -06:00
kernel_flush :
2010-12-18 16:49:57 +01:00
.word v7_flush_dcache_all
2010-12-20 14:05:07 -06:00
l2dis_3630 :
2010-12-18 16:49:57 +01:00
.word 0
2010-12-20 14:05:04 -06:00
/ *
* When e x p o r t i n g t o u s e r s p a c e w h i l e t h e c o u n t e r s a r e i n S R A M ,
* these 2 w o r d s n e e d t o b e a t t h e e n d t o f a c i l i t a t e r e t r i v a l !
* /
kick_counter :
.word 0
wait_dll_lock_counter :
.word 0
2010-12-18 16:44:45 +01:00
2009-05-28 10:56:16 -07:00
ENTRY( o m a p34 x x _ c p u _ s u s p e n d _ s z )
.word . - omap3 4 x x _ c p u _ s u s p e n d