2012-07-23 07:35:30 +04:00
# include < l i n u x / l i n k a g e . h >
# include < a s m / b l a c k f i n . h >
# include < a s m / d p m c . h >
# include < a s m / c o n t e x t . S >
# define P M _ S T A C K ( C O R E A _ L 1 _ S C R A T C H _ S T A R T + L 1 _ S C R A T C H _ L E N G T H - 1 2 )
.section .l1 .text
ENTRY( _ e n t e r _ h i b e r n a t e )
/* switch stack to L1 scratch, prepare for ddr srfr */
P0 . H = H I ( P M _ S T A C K ) ;
P0 . L = L O ( P M _ S T A C K ) ;
SP = P 0 ;
call _ b f60 9 _ d d r _ s r ;
call _ b f i n _ h i b e r n a t e _ s y s c o n t r o l ;
P0 . H = H I ( D P M 0 _ R E S T O R E 4 ) ;
P0 . L = L O ( D P M 0 _ R E S T O R E 4 ) ;
P1 . H = _ b f60 9 _ p m _ d a t a ;
P1 . L = _ b f60 9 _ p m _ d a t a ;
[ P0 ] = P 1 ;
P0 . H = H I ( D P M 0 _ C T L ) ;
P0 . L = L O ( D P M 0 _ C T L ) ;
R3 . H = H I ( 0 x00 0 0 0 0 1 0 ) ;
R3 . L = L O ( 0 x00 0 0 0 0 1 0 ) ;
bfin_ i n i t _ p m _ b e n c h _ c y c l e s ;
[ P0 ] = R 3 ;
SSYNC;
ENDPROC( _ e n t e r _ h i b e r n a t e )
/ * DPM w a k e u p i n t e r r u p t w o n ' t w a k e u p c o r e o n b f60 x i f i t s c o r e I M A S K
* is d i s a b l e d . T h i s b e h a v i o r d i f f e r f r o m b f5 x x s e r i a l p r o c e s s o r .
* /
ENTRY( _ d u m m y _ d e e p s l e e p )
[ - - sp] = S Y S C F G ;
[ - - sp] = ( R 7 : 0 ,P 5 : 0 ) ;
cli r0 ;
/* get wake up interrupt ID */
P0 . l = L O ( S E C _ S C I _ B A S E + S E C _ C S I D ) ;
P0 . h = H I ( S E C _ S C I _ B A S E + S E C _ C S I D ) ;
R0 = [ P 0 ] ;
/* ACK wake up interrupt in SEC */
P1 . l = L O ( S E C _ E N D ) ;
P1 . h = H I ( S E C _ E N D ) ;
[ P1 ] = R 0 ;
SSYNC;
/* restore EVT 11 entry */
p0 . h = h i ( E V T 1 1 ) ;
p0 . l = l o ( E V T 1 1 ) ;
p1 . h = _ e v t _ e v t 1 1 ;
p1 . l = _ e v t _ e v t 1 1 ;
[ p0 ] = p1 ;
SSYNC;
( R7 : 0 , P5 : 0 ) = [ sp+ + ] ;
SYSCFG = [ s p + + ] ;
RTI;
ENDPROC( _ d u m m y _ d e e p s l e e p )
ENTRY( _ e n t e r _ d e e p s l e e p )
2012-07-18 10:17:46 +04:00
LINK 0 x C ;
2012-07-23 07:35:30 +04:00
[ - - sp] = ( R 7 : 0 ,P 5 : 0 ) ;
/* Change EVT 11 entry to dummy handler for wake up event */
p0 . h = h i ( E V T 1 1 ) ;
p0 . l = l o ( E V T 1 1 ) ;
p1 . h = _ d u m m y _ d e e p s l e e p ;
p1 . l = _ d u m m y _ d e e p s l e e p ;
[ p0 ] = p1 ;
P0 . H = H I ( P M _ S T A C K ) ;
P0 . L = L O ( P M _ S T A C K ) ;
EX_ S C R A T C H _ R E G = S P ;
SP = P 0 ;
SSYNC;
/* should put ddr to self refresh mode before sleep */
call _ b f60 9 _ d d r _ s r ;
/* Set DPM controller to deep sleep mode */
P0 . H = H I ( D P M 0 _ C T L ) ;
P0 . L = L O ( D P M 0 _ C T L ) ;
R3 . H = H I ( 0 x00 0 0 0 0 0 8 ) ;
R3 . L = L O ( 0 x00 0 0 0 0 0 8 ) ;
[ P0 ] = R 3 ;
CSYNC;
/* Enable evt 11 in IMASK before idle, otherwise core doesn't wake up. */
r0 . l = 0 x80 0 ;
r0 . h = 0 ;
sti r0 ;
SSYNC;
2012-05-31 14:40:20 +04:00
bfin_ i n i t _ p m _ b e n c h _ c y c l e s ;
2012-07-23 07:35:30 +04:00
/* Fall into deep sleep in idle*/
idle;
SSYNC;
/* Restore PLL after wake up from deep sleep */
call _ b f60 9 _ r e s u m e _ c c b u f ;
/* turn ddr out of self refresh mode */
call _ b f60 9 _ d d r _ s r _ e x i t ;
SP = E X _ S C R A T C H _ R E G ;
( R7 : 0 , P5 : 0 ) = [ SP+ + ] ;
UNLINK;
RTS;
ENDPROC( _ e n t e r _ d e e p s l e e p )
.section .text
ENTRY( _ b f60 9 _ h i b e r n a t e )
bfin_ c p u _ r e g _ s a v e ;
bfin_ c o r e _ m m r _ s a v e ;
P0 . H = _ b f60 9 _ p m _ d a t a ;
P0 . L = _ b f60 9 _ p m _ d a t a ;
R1 . H = 0 x D E A D ;
R1 . L = 0 x B E E F ;
R2 . H = . L p m _ r e s u m e _ h e r e ;
R2 . L = . L p m _ r e s u m e _ h e r e ;
[ P0 + + ] = R 1 ;
[ P0 + + ] = R 2 ;
[ P0 + + ] = S P ;
P1 . H = _ e n t e r _ h i b e r n a t e ;
P1 . L = _ e n t e r _ h i b e r n a t e ;
call ( P 1 ) ;
.Lpm_resume_here :
bfin_ c o r e _ m m r _ r e s t o r e ;
bfin_ c p u _ r e g _ r e s t o r e ;
[ - - sp] = R E T I ; /* Clear Global Interrupt Disable */
SP + = 4 ;
RTS;
ENDPROC( _ b f60 9 _ h i b e r n a t e )