2009-12-17 15:59:31 +03:00
/ *
* ( C) C o p y r i g h t 2 0 0 9 , T e x a s I n s t r u m e n t s , I n c . h t t p : / / w w w . t i . c o m /
*
* 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
* version 2 a s p u b l i s h e d 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 .
*
* 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
* /
/* replicated define because linux/bitops.h cannot be included in assembly */
# define B I T ( n r ) ( 1 < < ( n r ) )
# 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 < m a c h / p s c . h >
2011-07-06 06:52:57 +04:00
# include < m a c h / d d r2 . h >
2009-12-17 15:59:31 +03:00
# include " c l o c k . h "
/* Arbitrary, hardware currently does not update PHYRDY correctly */
# define P H Y R D Y _ C Y C L E S 0 x10 0 0
/* Assume 25 MHz speed for the cycle conversions since PLLs are bypassed */
# define P L L _ B Y P A S S _ C Y C L E S ( P L L _ B Y P A S S _ T I M E * 2 5 )
# define P L L _ R E S E T _ C Y C L E S ( P L L _ R E S E T _ T I M E * 2 5 )
# define P L L _ L O C K _ C Y C L E S ( P L L _ L O C K _ T I M E * 2 5 )
# define D E E P S L E E P _ S L E E P E N A B L E _ B I T B I T ( 3 1 )
.text
/ *
* Move D a V i n c i i n t o d e e p s l e e p s t a t e
*
* Note : This c o d e i s c o p i e d t o i n t e r n a l S R A M b y P M c o d e . W h e n t h e D a V i n c i
* wakes u p i t c o n t i n u e s e x e c u t i o n a t t h e p o i n t i t w e n t t o s l e e p .
* Register U s a g e :
* r0 : contains v i r t u a l b a s e f o r D D R 2 c o n t r o l l e r
* r1 : contains v i r t u a l b a s e f o r D D R 2 P o w e r a n d S l e e p c o n t r o l l e r ( P S C )
* r2 : contains P S C n u m b e r f o r D D R 2
* r3 : contains v i r t u a l b a s e D D R 2 P L L c o n t r o l l e r
* r4 : contains v i r t u a l a d d r e s s o f t h e D E E P S L E E P r e g i s t e r
* /
ENTRY( d a v i n c i _ c p u _ s u s p e n d )
stmfd s p ! , { r0 - r12 , l r } @ save registers on stack
ldr i p , C A C H E _ F L U S H
blx i p
ldmia r0 , { r0 - r4 }
/ *
* Switch D D R t o s e l f - r e f r e s h m o d e .
* /
/* calculate SDRCR address */
ldr i p , [ r0 , #D D R 2 _ S D R C R _ O F F S E T ]
bic i p , i p , #D D R 2 _ S R P D _ B I T
orr i p , i p , #D D R 2 _ L P M O D E N _ B I T
str i p , [ r0 , #D D R 2 _ S D R C R _ O F F S E T ]
ldr i p , [ r0 , #D D R 2 _ S D R C R _ O F F S E T ]
orr i p , i p , #D D R 2 _ M C L K S T O P E N _ B I T
str i p , [ r0 , #D D R 2 _ S D R C R _ O F F S E T ]
mov i p , #P H Y R D Y _ C Y C L E S
1 : subs i p , i p , #0x1
bne 1 b
/* Disable DDR2 LPSC */
mov r7 , r0
mov r0 , #0x2
bl d a v i n c i _ d d r _ p s c _ c o n f i g
mov r0 , r7
/* Disable clock to DDR PHY */
ldr i p , [ r3 , #P L L D I V 1 ]
bic i p , i p , #P L L D I V _ E N
str i p , [ r3 , #P L L D I V 1 ]
/* Put the DDR PLL in bypass and power down */
ldr i p , [ r3 , #P L L C T L ]
bic i p , i p , #P L L C T L _ P L L E N S R C
bic i p , i p , #P L L C T L _ P L L E N
str i p , [ r3 , #P L L C T L ]
/* Wait for PLL to switch to bypass */
mov i p , #P L L _ B Y P A S S _ C Y C L E S
2 : subs i p , i p , #0x1
bne 2 b
/* Power down the PLL */
ldr i p , [ r3 , #P L L C T L ]
orr i p , i p , #P L L C T L _ P L L P W R D N
str i p , [ r3 , #P L L C T L ]
/* Go to deep sleep */
ldr i p , [ r4 ]
orr i p , i p , #D E E P S L E E P _ S L E E P E N A B L E _ B I T
/* System goes to sleep beyond after this instruction */
str i p , [ r4 ]
/* Wake up from sleep */
/* Clear sleep enable */
ldr i p , [ r4 ]
bic i p , i p , #D E E P S L E E P _ S L E E P E N A B L E _ B I T
str i p , [ r4 ]
/* initialize the DDR PLL controller */
/* Put PLL in reset */
ldr i p , [ r3 , #P L L C T L ]
bic i p , i p , #P L L C T L _ P L L R S T
str i p , [ r3 , #P L L C T L ]
/* Clear PLL power down */
ldr i p , [ r3 , #P L L C T L ]
bic i p , i p , #P L L C T L _ P L L P W R D N
str i p , [ r3 , #P L L C T L ]
mov i p , #P L L _ R E S E T _ C Y C L E S
3 : subs i p , i p , #0x1
bne 3 b
/* Bring PLL out of reset */
ldr i p , [ r3 , #P L L C T L ]
orr i p , i p , #P L L C T L _ P L L R S T
str i p , [ r3 , #P L L C T L ]
/* Wait for PLL to lock (assume prediv = 1, 25MHz OSCIN) */
mov i p , #P L L _ L O C K _ C Y C L E S
4 : subs i p , i p , #0x1
bne 4 b
/* Remove PLL from bypass mode */
ldr i p , [ r3 , #P L L C T L ]
bic i p , i p , #P L L C T L _ P L L E N S R C
orr i p , i p , #P L L C T L _ P L L E N
str i p , [ r3 , #P L L C T L ]
/* Start 2x clock to DDR2 */
ldr i p , [ r3 , #P L L D I V 1 ]
orr i p , i p , #P L L D I V _ E N
str i p , [ r3 , #P L L D I V 1 ]
/* Enable VCLK */
/* Enable DDR2 LPSC */
mov r7 , r0
mov r0 , #0x3
bl d a v i n c i _ d d r _ p s c _ c o n f i g
mov r0 , r7
/* clear MCLKSTOPEN */
ldr i p , [ r0 , #D D R 2 _ S D R C R _ O F F S E T ]
bic i p , i p , #D D R 2 _ M C L K S T O P E N _ B I T
str i p , [ r0 , #D D R 2 _ S D R C R _ O F F S E T ]
ldr i p , [ r0 , #D D R 2 _ S D R C R _ O F F S E T ]
bic i p , i p , #D D R 2 _ L P M O D E N _ B I T
str i p , [ r0 , #D D R 2 _ S D R C R _ O F F S E T ]
/* Restore registers and return */
ldmfd s p ! , { r0 - r12 , p c }
ENDPROC( d a v i n c i _ c p u _ s u s p e n d )
/ *
* Disables o r E n a b l e s D D R 2 L P S C
* Register U s a g e :
* r0 : Enable o r D i s a b l e L P S C r0 = 0 x3 = > E n a b l e , r0 = 0 x2 = > D i s a b l e L P S C
* r1 : contains v i r t u a l b a s e f o r D D R 2 P o w e r a n d S l e e p c o n t r o l l e r ( P S C )
* r2 : contains P S C n u m b e r f o r D D R 2
* /
ENTRY( d a v i n c i _ d d r _ p s c _ c o n f i g )
/* Set next state in mdctl for DDR2 */
mov r6 , #M D C T L
add r6 , r6 , r2 , l s l #2
ldr i p , [ r1 , r6 ]
bic i p , i p , #M D S T A T _ S T A T E _ M A S K
orr i p , i p , r0
str i p , [ r1 , r6 ]
/* Enable the Power Domain Transition Command */
ldr i p , [ r1 , #P T C M D ]
orr i p , i p , #0x1
str i p , [ r1 , #P T C M D ]
/* Check for Transition Complete (PTSTAT) */
ptstat_done :
ldr i p , [ r1 , #P T S T A T ]
and i p , i p , #0x1
cmp i p , #0x0
bne p t s t a t _ d o n e
/* Check for DDR2 clock disable completion; */
mov r6 , #M D S T A T
add r6 , r6 , r2 , l s l #2
ddr2clk_stop_done :
ldr i p , [ r1 , r6 ]
and i p , i p , #M D S T A T _ S T A T E _ M A S K
cmp i p , r0
bne d d r2 c l k _ s t o p _ d o n e
mov p c , l r
ENDPROC( d a v i n c i _ d d r _ p s c _ c o n f i g )
CACHE_FLUSH :
2011-08-02 19:48:38 +04:00
# ifdef C O N F I G _ C P U _ V 6
.word v6_flush_kern_cache_all
# else
.word arm926_flush_kern_cache_all
# endif
2009-12-17 15:59:31 +03:00
ENTRY( d a v i n c i _ c p u _ s u s p e n d _ s z )
.word . - davinci_ c p u _ s u s p e n d
ENDPROC( d a v i n c i _ c p u _ s u s p e n d _ s z )