2006-05-16 14:54:37 +04:00
/ *
* linux/ a r c h / a r m / m a c h - p n x40 0 8 / s l e e p . S
*
* PNX4 0 0 8 s u p p o r t f o r S T O P m o d e a n d S D R A M s e l f - r e f r e s h
*
* Authors : Dmitry C h i g i r e v , V i t a l y W o o l < s o u r c e @mvista.com>
*
* 2 0 0 5 ( c) M o n t a V i s t a S o f t w a r e , I n c . T h i s f i l e i s l i c e n s e d u n d e r
* the 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 . T h i s p r o g r a m
* is l i c e n s e d " a s i s " w i t h o u t a n y w a r r a n t y o f a n y k i n d , w h e t h e r e x p r e s s
* or i m p l i e d .
* /
# 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 >
2006-05-16 14:54:37 +04:00
# define P W R M A N _ V A _ B A S E I O _ A D D R E S S ( P N X 4 0 0 8 _ P W R M A N _ B A S E )
# define P W R _ C T R L _ R E G _ O F F S 0 x44
# define S D R A M _ C F G _ V A _ B A S E I O _ A D D R E S S ( P N X 4 0 0 8 _ S D R A M _ C F G _ B A S E )
# define M P M C _ S T A T U S _ R E G _ O F F S 0 x4
.text
ENTRY( p n x40 0 8 _ c p u _ s u s p e n d )
@this function should be entered in Direct run mode.
@ save registers on stack
stmfd s p ! , { r0 - r6 , l r }
@ setup Power Manager base address in r4
@ and put it's value in r5
mov r4 , #( P W R M A N _ V A _ B A S E & 0xff000000 )
orr r4 , r4 , #( P W R M A N _ V A _ B A S E & 0x00ff0000 )
orr r4 , r4 , #( P W R M A N _ V A _ B A S E & 0x0000ff00 )
orr r4 , r4 , #( P W R M A N _ V A _ B A S E & 0x000000ff )
ldr r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ setup SDRAM controller base address in r2
@ and put it's value in r3
mov r2 , #( S D R A M _ C F G _ V A _ B A S E & 0xff000000 )
orr r2 , r2 , #( S D R A M _ C F G _ V A _ B A S E & 0x00ff0000 )
orr r2 , r2 , #( S D R A M _ C F G _ V A _ B A S E & 0x0000ff00 )
orr r2 , r2 , #( S D R A M _ C F G _ V A _ B A S E & 0x000000ff )
ldr r3 , [ r2 , #M P M C _ S T A T U S _ R E G _ O F F S ] @ e x t r a r e a d - H W b u g w o r k a r o u n d
@ clear SDRAM self-refresh bit latch
and r5 , r5 , #( ~ ( 1 < < 8 ) )
@ clear SDRAM self-refresh bit
and r5 , r5 , #( ~ ( 1 < < 9 ) )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ do save current bit settings in r1
mov r1 , r5
@ set SDRAM self-refresh bit
orr r5 , r5 , #( 1 < < 9 )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ set SDRAM self-refresh bit latch
orr r5 , r5 , #( 1 < < 8 )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ clear SDRAM self-refresh bit latch
and r5 , r5 , #( ~ ( 1 < < 8 ) )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ clear SDRAM self-refresh bit
and r5 , r5 , #( ~ ( 1 < < 9 ) )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ wait for SDRAM to get into self-refresh mode
2 : ldr r3 , [ r2 , #M P M C _ S T A T U S _ R E G _ O F F S ]
tst r3 , #( 1 < < 2 )
beq 2 b
@ to prepare SDRAM to get out of self-refresh mode after wakeup
orr r5 , r5 , #( 1 < < 7 )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ do enter stop mode
orr r5 , r5 , #( 1 < < 0 )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
nop
nop
nop
nop
nop
nop
nop
nop
nop
@ sleeping now...
@ coming out of STOP mode into Direct Run mode
@ clear STOP mode and SDRAM self-refresh bits
str r1 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ wait for SDRAM to get out self-refresh mode
3 : ldr r3 , [ r2 , #M P M C _ S T A T U S _ R E G _ O F F S ]
tst r3 , #5
bne 3 b
@ restore regs and return
ldmfd s p ! , { r0 - r6 , p c }
ENTRY( p n x40 0 8 _ c p u _ s u s p e n d _ s z )
.word . - pnx4 0 0 8 _ c p u _ s u s p e n d
ENTRY( p n x40 0 8 _ c p u _ s t a n d b y )
@ save registers on stack
stmfd s p ! , { r0 - r6 , l r }
@ setup Power Manager base address in r4
@ and put it's value in r5
mov r4 , #( P W R M A N _ V A _ B A S E & 0xff000000 )
orr r4 , r4 , #( P W R M A N _ V A _ B A S E & 0x00ff0000 )
orr r4 , r4 , #( P W R M A N _ V A _ B A S E & 0x0000ff00 )
orr r4 , r4 , #( P W R M A N _ V A _ B A S E & 0x000000ff )
ldr r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ setup SDRAM controller base address in r2
@ and put it's value in r3
mov r2 , #( S D R A M _ C F G _ V A _ B A S E & 0xff000000 )
orr r2 , r2 , #( S D R A M _ C F G _ V A _ B A S E & 0x00ff0000 )
orr r2 , r2 , #( S D R A M _ C F G _ V A _ B A S E & 0x0000ff00 )
orr r2 , r2 , #( S D R A M _ C F G _ V A _ B A S E & 0x000000ff )
ldr r3 , [ r2 , #M P M C _ S T A T U S _ R E G _ O F F S ] @ e x t r a r e a d - H W b u g w o r k a r o u n d
@ clear SDRAM self-refresh bit latch
and r5 , r5 , #( ~ ( 1 < < 8 ) )
@ clear SDRAM self-refresh bit
and r5 , r5 , #( ~ ( 1 < < 9 ) )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ do save current bit settings in r1
mov r1 , r5
@ set SDRAM self-refresh bit
orr r5 , r5 , #( 1 < < 9 )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ set SDRAM self-refresh bit latch
orr r5 , r5 , #( 1 < < 8 )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ clear SDRAM self-refresh bit latch
and r5 , r5 , #( ~ ( 1 < < 8 ) )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ clear SDRAM self-refresh bit
and r5 , r5 , #( ~ ( 1 < < 9 ) )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ wait for SDRAM to get into self-refresh mode
2 : ldr r3 , [ r2 , #M P M C _ S T A T U S _ R E G _ O F F S ]
tst r3 , #( 1 < < 2 )
beq 2 b
@ set 'get out of self-refresh mode after wakeup' bit
orr r5 , r5 , #( 1 < < 7 )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
mcr p15 , 0 , r0 , c7 , c0 , 4 @ kinda sleeping now...
@ set SDRAM self-refresh bit latch
orr r5 , r5 , #( 1 < < 8 )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ clear SDRAM self-refresh bit latch
and r5 , r5 , #( ~ ( 1 < < 8 ) )
str r5 , [ r4 , #P W R _ C T R L _ R E G _ O F F S ]
@ wait for SDRAM to get out self-refresh mode
3 : ldr r3 , [ r2 , #M P M C _ S T A T U S _ R E G _ O F F S ]
tst r3 , #5
bne 3 b
@ restore regs and return
ldmfd s p ! , { r0 - r6 , p c }
ENTRY( p n x40 0 8 _ c p u _ s t a n d b y _ s z )
.word . - pnx4 0 0 8 _ c p u _ s t a n d b y
ENTRY( p n x40 0 8 _ c a c h e _ c l e a n _ i n v a l i d a t e )
stmfd s p ! , { r0 - r6 , l r }
# ifdef C O N F I G _ C P U _ D C A C H E _ W R I T E T H R O U G H
mcr p15 , 0 , i p , c7 , c6 , 0 @ invalidate D cache
# else
1 : mrc p15 , 0 , r15 , c7 , c14 , 3 @ test,clean,invalidate
bne 1 b
# endif
ldmfd s p ! , { r0 - r6 , p c }