2005-07-10 22:58:15 +04:00
/ *
2006-04-02 20:46:25 +04:00
* linux/ a r c h / a r m / m a c h - o m a p1 / s l e e p . S
2005-07-10 22:58:15 +04:00
*
2005-11-10 17:26:50 +03:00
* Low- l e v e l O M A P 7 3 0 / 1 5 1 0 / 1 6 1 0 s l e e p / w a k e U p s u p p o r t
2005-07-10 22:58:15 +04:00
*
* Initial S A 1 1 1 0 c o d e :
* Copyright ( c ) 2 0 0 1 C l i f f B r a k e < c b r a k e @accelent.com>
*
* Adapted f o r P X A b y N i c o l a s P i t r e :
* Copyright ( c ) 2 0 0 2 M o n t a V i s t a S o f t w a r e , I n c .
*
* Support f o r O M A P 1 5 1 0 / 1 6 1 0 b y D i r k B e h m e < d i r k . b e h m e @de.bosch.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 it
* under 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 p u b l i s h e d b y t h e
* Free S o f t w a r e F o u n d a t i o n ; either version 2 of the License, or (at your
* option) a n y l a t e r v e r s i o n .
*
* THIS S O F T W A R E I S P R O V I D E D ` ` A S I S ' ' A N D A N Y E X P R E S S O R I M P L I E D
* WARRANTIES, I N C L U D I N G , B U T N O T L I M I T E D T O , T H E I M P L I E D W A R R A N T I E S O F
* MERCHANTABILITY A N D 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 A R E D I S C L A I M E D . I N
* NO E V E N T S H A L L T H E A U T H O R B E L I A B L E F O R A N Y D I R E C T , I N D I R E C T ,
* INCIDENTAL, S P E C I A L , E X E M P L A R Y , O R C O N S E Q U E N T I A L D A M A G E S ( I N C L U D I N G , B U T
* NOT L I M I T E D T O , P R O C U R E M E N T O F S U B S T I T U T E G O O D S O R S E R V I C E S ; LOSS OF
* USE, D A T A , O R P R O F I T S ; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY T H E O R Y O F L I A B I L I T Y , W H E T H E R I N C O N T R A C T , S T R I C T L I A B I L I T Y , O R T O R T
* ( INCLUDING N E G L I G E N C E O R O T H E R W I S E ) A R I S I N G I N A N Y W A Y O U T O F T H E U S E O F
* THIS S O F T W A R E , E V E N I F A D V I S E D O F T H E P O S S I B I L I T Y O F S U C H D A M A G E .
*
* 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 a l o n g
* with t h i s p r o g r a m ; if not, write to the Free Software Foundation, Inc.,
* 6 7 5 Mass A v e , C a m b r i d g e , M A 0 2 1 3 9 , 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 >
# include < a s m / a r c h / i o . h >
# include < a s m / a r c h / p m . h >
.text
/ *
* Forces O M A P i n t o i d l e s t a t e
*
* omapXXXX_ i d l e _ l o o p _ s u s p e n d ( )
*
* Note : 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 . W h e n t h e O M A P
* 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 .
*
* Note : Because o f s l i g h t l y d i f f e r e n t c o n f i g u r a t i o n v a l u e s w e h a v e
* processor s p e c i f i c f u n c t i o n s h e r e .
* /
2005-11-10 17:26:50 +03:00
# if d e f i n e d ( C O N F I G _ A R C H _ O M A P 7 3 0 )
ENTRY( o m a p73 0 _ i d l e _ l o o p _ s u s p e n d )
stmfd s p ! , { r0 - r12 , l r } @ save registers on stack
@ load base address of ARM_IDLECT1 and ARM_IDLECT2
mov r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0xff000000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x00ff0000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x0000ff00
@ turn off clock domains
@ get ARM_IDLECT2 into r2
ldrh r2 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
mov r5 , #O M A P 730 _ I D L E C T 2 _ S L E E P _ V A L & 0 x f f
orr r5 , r5 , #O M A P 730 _ I D L E C T 2 _ S L E E P _ V A L & 0 x f f00
strh r5 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
@ request ARM idle
@ get ARM_IDLECT1 into r1
ldrh r1 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
orr r3 , r1 , #O M A P 730 _ I D L E _ L O O P _ R E Q U E S T & 0 x f f f f
strh r3 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
mov r5 , #I D L E _ W A I T _ C Y C L E S & 0xff
orr r5 , r5 , #I D L E _ W A I T _ C Y C L E S & 0xff00
l_730 : subs r5 , r5 , #1
bne l _ 7 3 0
/ *
* Let' s w a i t f o r t h e n e x t c l o c k t i c k t o w a k e u s u p .
* /
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c0 , 4 @ wait for interrupt
/ *
* omap7 3 0 _ i d l e _ l o o p _ s u s p e n d ( ) ' s r e s u m e p o i n t .
*
* It w i l l j u s t s t a r t e x e c u t i n g h e r e , s o w e ' l l r e s t o r e s t u f f f r o m t h e
* stack, r e s e t t h e A R M _ I D L E C T 1 a n d A R M _ I D L E C T 2 .
* /
@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
strh r2 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
strh r1 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
ldmfd s p ! , { r0 - r12 , p c } @ restore regs and return
ENTRY( o m a p73 0 _ i d l e _ l o o p _ s u s p e n d _ s z )
.word . - omap7 3 0 _ i d l e _ l o o p _ s u s p e n d
# endif / * C O N F I G _ A R C H _ O M A P 7 3 0 * /
# ifdef C O N F I G _ A R C H _ O M A P 1 5 X X
2005-07-10 22:58:15 +04:00
ENTRY( o m a p15 1 0 _ i d l e _ l o o p _ s u s p e n d )
stmfd s p ! , { r0 - r12 , l r } @ save registers on stack
@ load base address of ARM_IDLECT1 and ARM_IDLECT2
mov r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0xff000000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x00ff0000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x0000ff00
@ turn off clock domains
@ get ARM_IDLECT2 into r2
ldrh r2 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
mov r5 , #O M A P 1510 _ I D L E _ C L O C K _ D O M A I N S & 0 x f f
2005-09-07 20:20:26 +04:00
orr r5 , r5 , #O M A P 1510 _ I D L E _ C L O C K _ D O M A I N S & 0 x f f00
2005-07-10 22:58:15 +04:00
strh r5 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
@ request ARM idle
@ get ARM_IDLECT1 into r1
ldrh r1 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
orr r3 , r1 , #O M A P 1510 _ I D L E _ L O O P _ R E Q U E S T & 0 x f f f f
strh r3 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
mov r5 , #I D L E _ W A I T _ C Y C L E S & 0xff
2005-09-07 20:20:26 +04:00
orr r5 , r5 , #I D L E _ W A I T _ C Y C L E S & 0xff00
2005-07-10 22:58:15 +04:00
l_1510 : subs r5 , r5 , #1
bne l _ 1 5 1 0
/ *
* Let' s w a i t f o r t h e n e x t c l o c k t i c k t o w a k e u s u p .
* /
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c0 , 4 @ wait for interrupt
/ *
* omap1 5 1 0 _ i d l e _ l o o p _ s u s p e n d ( ) ' s r e s u m e p o i n t .
*
* It w i l l j u s t s t a r t e x e c u t i n g h e r e , s o w e ' l l r e s t o r e s t u f f f r o m t h e
* stack, r e s e t t h e A R M _ I D L E C T 1 a n d A R M _ I D L E C T 2 .
* /
@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
strh r2 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
strh r1 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
2005-09-07 20:20:26 +04:00
ldmfd s p ! , { r0 - r12 , p c } @ restore regs and return
2005-07-10 22:58:15 +04:00
ENTRY( o m a p15 1 0 _ i d l e _ l o o p _ s u s p e n d _ s z )
.word . - omap1 5 1 0 _ i d l e _ l o o p _ s u s p e n d
2005-11-10 17:26:50 +03:00
# endif / * C O N F I G _ A R C H _ O M A P 1 5 X X * /
2005-07-10 22:58:15 +04:00
# if d e f i n e d ( C O N F I G _ A R C H _ O M A P 1 6 X X )
ENTRY( o m a p16 1 0 _ i d l e _ l o o p _ s u s p e n d )
stmfd s p ! , { r0 - r12 , l r } @ save registers on stack
@ load base address of ARM_IDLECT1 and ARM_IDLECT2
mov r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0xff000000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x00ff0000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x0000ff00
@ turn off clock domains
@ get ARM_IDLECT2 into r2
ldrh r2 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
2005-09-07 20:20:26 +04:00
mov r5 , #O M A P 1610 _ I D L E C T 2 _ S L E E P _ V A L & 0 x f f
orr r5 , r5 , #O M A P 1610 _ I D L E C T 2 _ S L E E P _ V A L & 0 x f f00
2005-07-10 22:58:15 +04:00
strh r5 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
@ request ARM idle
@ get ARM_IDLECT1 into r1
ldrh r1 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
orr r3 , r1 , #O M A P 1610 _ I D L E _ L O O P _ R E Q U E S T & 0 x f f f f
strh r3 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
mov r5 , #I D L E _ W A I T _ C Y C L E S & 0xff
2005-09-07 20:20:26 +04:00
orr r5 , r5 , #I D L E _ W A I T _ C Y C L E S & 0xff00
2005-07-10 22:58:15 +04:00
l_1610 : subs r5 , r5 , #1
bne l _ 1 6 1 0
/ *
* Let' s w a i t f o r t h e n e x t c l o c k t i c k t o w a k e u s u p .
* /
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c0 , 4 @ wait for interrupt
/ *
* omap1 6 1 0 _ i d l e _ l o o p _ s u s p e n d ( ) ' s r e s u m e p o i n t .
*
* It w i l l j u s t s t a r t e x e c u t i n g h e r e , s o w e ' l l r e s t o r e s t u f f f r o m t h e
* stack, r e s e t t h e A R M _ I D L E C T 1 a n d A R M _ I D L E C T 2 .
* /
@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
strh r2 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
strh r1 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
2005-09-07 20:20:26 +04:00
ldmfd s p ! , { r0 - r12 , p c } @ restore regs and return
2005-07-10 22:58:15 +04:00
ENTRY( o m a p16 1 0 _ i d l e _ l o o p _ s u s p e n d _ s z )
.word . - omap1 6 1 0 _ i d l e _ l o o p _ s u s p e n d
# endif / * C O N F I G _ A R C H _ O M A P 1 6 X X * /
/ *
* Forces O M A P i n t o d e e p s l e e p s t a t e
*
* omapXXXX_ c p u _ s u s p e n d ( )
*
* The v a l u e s o f t h e r e g i s t e r s A R M _ I D L E C T 1 a n d A R M _ I D L E C T 2 a r e p a s s e d
* as a r g 0 a n d a r g 1 f r o m c a l l e r . a r g 0 i s s t o r e d i n r e g i s t e r r0 a n d a r g 1
* in r e g i s t e r r1 .
*
* Note : 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 . W h e n t h e O M A P
* 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 .
*
* Note : Because o f e r r a t a w o r k a r o u n d s w e h a v e p r o c e s s o r s p e c i f i c f u n c t i o n s
* here. T h e y a r e m o s t l y t h e s a m e , b u t s l i g h t l y d i f f e r e n t .
*
* /
2005-11-10 17:26:50 +03:00
# if d e f i n e d ( C O N F I G _ A R C H _ O M A P 7 3 0 )
ENTRY( o m a p73 0 _ c p u _ s u s p e n d )
@ save registers on stack
stmfd s p ! , { r0 - r12 , l r }
@ Drain write cache
mov r4 , #0
mcr p15 , 0 , r0 , c7 , c10 , 4
nop
@ load base address of Traffic Controller
mov r6 , #T C M I F _ A S M _ B A S E & 0xff000000
orr r6 , r6 , #T C M I F _ A S M _ B A S E & 0x00ff0000
orr r6 , r6 , #T C M I F _ A S M _ B A S E & 0x0000ff00
@ prepare to put SDRAM into self-refresh manually
ldr r7 , [ r6 , #E M I F F _ S D R A M _ C O N F I G _ A S M _ O F F S E T & 0xff ]
orr r9 , r7 , #S E L F _ R E F R E S H _ M O D E & 0xff000000
orr r9 , r9 , #S E L F _ R E F R E S H _ M O D E & 0x000000ff
str r9 , [ r6 , #E M I F F _ S D R A M _ C O N F I G _ A S M _ O F F S E T & 0xff ]
@ prepare to put EMIFS to Sleep
ldr r8 , [ r6 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
orr r9 , r8 , #I D L E _ E M I F S _ R E Q U E S T & 0xff
str r9 , [ r6 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
@ load base address of ARM_IDLECT1 and ARM_IDLECT2
mov r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0xff000000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x00ff0000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x0000ff00
@ turn off clock domains
@ do not disable PERCK (0x04)
mov r5 , #O M A P 730 _ I D L E C T 2 _ S L E E P _ V A L & 0 x f f
orr r5 , r5 , #O M A P 730 _ I D L E C T 2 _ S L E E P _ V A L & 0 x f f00
strh r5 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
@ request ARM idle
mov r3 , #O M A P 730 _ I D L E C T 1 _ S L E E P _ V A L & 0 x f f
orr r3 , r3 , #O M A P 730 _ I D L E C T 1 _ S L E E P _ V A L & 0 x f f00
strh r3 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
@ disable instruction cache
mrc p15 , 0 , r9 , c1 , c0 , 0
bic r2 , r9 , #0x1000
mcr p15 , 0 , r2 , c1 , c0 , 0
nop
/ *
* Let' s w a i t f o r t h e n e x t w a k e u p e v e n t t o w a k e u s u p . r0 c a n ' t b e
* used h e r e b e c a u s e r0 h o l d s A R M _ I D L E C T 1
* /
mov r2 , #0
mcr p15 , 0 , r2 , c7 , c0 , 4 @ wait for interrupt
/ *
* omap7 3 0 _ c p u _ s u s p e n d ( ) ' s r e s u m e p o i n t .
*
* It w i l l j u s t s t a r t e x e c u t i n g h e r e , s o w e ' l l r e s t o r e s t u f f f r o m t h e
* stack.
* /
@ re-enable Icache
mcr p15 , 0 , r9 , c1 , c0 , 0
@ reset the ARM_IDLECT1 and ARM_IDLECT2.
strh r1 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
strh r0 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
@ Restore EMIFF controls
str r7 , [ r6 , #E M I F F _ S D R A M _ C O N F I G _ A S M _ O F F S E T & 0xff ]
str r8 , [ r6 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
@ restore regs and return
ldmfd s p ! , { r0 - r12 , p c }
ENTRY( o m a p73 0 _ c p u _ s u s p e n d _ s z )
.word . - omap7 3 0 _ c p u _ s u s p e n d
# endif / * C O N F I G _ A R C H _ O M A P 7 3 0 * /
# ifdef C O N F I G _ A R C H _ O M A P 1 5 X X
2005-07-10 22:58:15 +04:00
ENTRY( o m a p15 1 0 _ c p u _ s u s p e n d )
@ save registers on stack
stmfd s p ! , { r0 - r12 , l r }
@ load base address of Traffic Controller
mov r4 , #T C M I F _ A S M _ B A S E & 0xff000000
orr r4 , r4 , #T C M I F _ A S M _ B A S E & 0x00ff0000
orr r4 , r4 , #T C M I F _ A S M _ B A S E & 0x0000ff00
@ work around errata of OMAP1510 PDE bit for TC shut down
@ clear PDE bit
ldr r5 , [ r4 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
bic r5 , r5 , #P D E _ B I T & 0xff
str r5 , [ r4 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
@ set PWD_EN bit
and r5 , r5 , #P W D _ E N _ B I T & 0xff
str r5 , [ r4 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
@ prepare to put SDRAM into self-refresh manually
ldr r5 , [ r4 , #E M I F F _ S D R A M _ C O N F I G _ A S M _ O F F S E T & 0xff ]
orr r5 , r5 , #S E L F _ R E F R E S H _ M O D E & 0xff000000
orr r5 , r5 , #S E L F _ R E F R E S H _ M O D E & 0x000000ff
str r5 , [ r4 , #E M I F F _ S D R A M _ C O N F I G _ A S M _ O F F S E T & 0xff ]
@ prepare to put EMIFS to Sleep
ldr r5 , [ r4 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
orr r5 , r5 , #I D L E _ E M I F S _ R E Q U E S T & 0xff
str r5 , [ r4 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
@ load base address of ARM_IDLECT1 and ARM_IDLECT2
mov r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0xff000000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x00ff0000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x0000ff00
@ turn off clock domains
mov r5 , #O M A P 1510 _ I D L E _ C L O C K _ D O M A I N S & 0 x f f
2005-09-07 20:20:26 +04:00
orr r5 , r5 , #O M A P 1510 _ I D L E _ C L O C K _ D O M A I N S & 0 x f f00
2005-07-10 22:58:15 +04:00
strh r5 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
@ request ARM idle
mov r3 , #O M A P 1510 _ D E E P _ S L E E P _ R E Q U E S T & 0 x f f
orr r3 , r3 , #O M A P 1510 _ D E E P _ S L E E P _ R E Q U E S T & 0 x f f00
strh r3 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
mov r5 , #I D L E _ W A I T _ C Y C L E S & 0xff
2005-09-07 20:20:26 +04:00
orr r5 , r5 , #I D L E _ W A I T _ C Y C L E S & 0xff00
2005-07-10 22:58:15 +04:00
l_1510_2 :
subs r5 , r5 , #1
bne l _ 1 5 1 0 _ 2
/ *
* Let' s w a i t f o r t h e n e x t w a k e u p e v e n t t o w a k e u s u p . r0 c a n ' t b e
* used h e r e b e c a u s e r0 h o l d s A R M _ I D L E C T 1
* /
mov r2 , #0
mcr p15 , 0 , r2 , c7 , c0 , 4 @ wait for interrupt
/ *
* omap1 5 1 0 _ c p u _ s u s p e n d ( ) ' s r e s u m e p o i n t .
*
* It w i l l j u s t s t a r t e x e c u t i n g h e r e , s o w e ' l l r e s t o r e s t u f f f r o m t h e
* stack, r e s e t t h e A R M _ I D L E C T 1 a n d A R M _ I D L E C T 2 .
* /
strh r1 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
strh r0 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
@ restore regs and return
2005-09-07 20:20:26 +04:00
ldmfd s p ! , { r0 - r12 , p c }
2005-07-10 22:58:15 +04:00
ENTRY( o m a p15 1 0 _ c p u _ s u s p e n d _ s z )
.word . - omap1 5 1 0 _ c p u _ s u s p e n d
2005-11-10 17:26:50 +03:00
# endif / * C O N F I G _ A R C H _ O M A P 1 5 X X * /
2005-07-10 22:58:15 +04:00
# if d e f i n e d ( C O N F I G _ A R C H _ O M A P 1 6 X X )
ENTRY( o m a p16 1 0 _ c p u _ s u s p e n d )
@ save registers on stack
stmfd s p ! , { r0 - r12 , l r }
2005-09-07 20:20:26 +04:00
@ Drain write cache
mov r4 , #0
mcr p15 , 0 , r0 , c7 , c10 , 4
nop
2006-04-02 20:46:25 +04:00
@ Load base address of Traffic Controller
2005-09-07 20:20:26 +04:00
mov r6 , #T C M I F _ A S M _ B A S E & 0xff000000
orr r6 , r6 , #T C M I F _ A S M _ B A S E & 0x00ff0000
orr r6 , r6 , #T C M I F _ A S M _ B A S E & 0x0000ff00
2005-07-10 22:58:15 +04:00
2006-04-02 20:46:25 +04:00
@ Prepare to put SDRAM into self-refresh manually
2005-09-07 20:20:26 +04:00
ldr r7 , [ r6 , #E M I F F _ S D R A M _ C O N F I G _ A S M _ O F F S E T & 0xff ]
orr r9 , r7 , #S E L F _ R E F R E S H _ M O D E & 0xff000000
orr r9 , r9 , #S E L F _ R E F R E S H _ M O D E & 0x000000ff
str r9 , [ r6 , #E M I F F _ S D R A M _ C O N F I G _ A S M _ O F F S E T & 0xff ]
2005-07-10 22:58:15 +04:00
2006-04-02 20:46:25 +04:00
@ Prepare to put EMIFS to Sleep
2005-09-07 20:20:26 +04:00
ldr r8 , [ r6 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
orr r9 , r8 , #I D L E _ E M I F S _ R E Q U E S T & 0xff
str r9 , [ r6 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
2005-07-10 22:58:15 +04:00
2006-04-02 20:46:25 +04:00
@ Load base address of ARM_IDLECT1 and ARM_IDLECT2
2005-07-10 22:58:15 +04:00
mov r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0xff000000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x00ff0000
orr r4 , r4 , #C L K G E N _ R E G _ A S M _ B A S E & 0x0000ff00
2006-04-02 20:46:25 +04:00
@ Turn off clock domains
@ Do not disable PERCK (0x04)
2005-09-07 20:20:26 +04:00
mov r5 , #O M A P 1610 _ I D L E C T 2 _ S L E E P _ V A L & 0 x f f
orr r5 , r5 , #O M A P 1610 _ I D L E C T 2 _ S L E E P _ V A L & 0 x f f00
2005-07-10 22:58:15 +04:00
strh r5 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
2006-04-02 20:46:25 +04:00
@ Request ARM idle
2005-09-07 20:20:26 +04:00
mov r3 , #O M A P 1610 _ I D L E C T 1 _ S L E E P _ V A L & 0 x f f
orr r3 , r3 , #O M A P 1610 _ I D L E C T 1 _ S L E E P _ V A L & 0 x f f00
2005-07-10 22:58:15 +04:00
strh r3 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
/ *
* Let' s w a i t f o r t h e n e x t w a k e u p e v e n t t o w a k e u s u p . r0 c a n ' t b e
* used h e r e b e c a u s e r0 h o l d s A R M _ I D L E C T 1
* /
mov r2 , #0
mcr p15 , 0 , r2 , c7 , c0 , 4 @ wait for interrupt
2006-04-02 20:46:25 +04:00
@ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
@ according to this formula:
@ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
@ Max DPLL_MULT = 18
@ DPLL_DIV = 1
@ ARMDIV = 1
@ => 74 nop-instructions
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop @10
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop @20
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop @30
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop @40
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop @50
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop @60
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop @70
nop
nop
nop
nop @74
2005-07-10 22:58:15 +04:00
/ *
* omap1 6 1 0 _ c p u _ s u s p e n d ( ) ' s r e s u m e p o i n t .
*
* It w i l l j u s t s t a r t e x e c u t i n g h e r e , s o w e ' l l r e s t o r e s t u f f f r o m t h e
2005-09-07 20:20:26 +04:00
* stack.
2005-07-10 22:58:15 +04:00
* /
2006-04-02 20:46:25 +04:00
@ Restore the ARM_IDLECT1 and ARM_IDLECT2.
2005-07-10 22:58:15 +04:00
strh r1 , [ r4 , #A R M _ I D L E C T 2 _ A S M _ O F F S E T & 0 x f f ]
strh r0 , [ r4 , #A R M _ I D L E C T 1 _ A S M _ O F F S E T & 0 x f f ]
2005-09-07 20:20:26 +04:00
@ Restore EMIFF controls
str r7 , [ r6 , #E M I F F _ S D R A M _ C O N F I G _ A S M _ O F F S E T & 0xff ]
str r8 , [ r6 , #E M I F S _ C O N F I G _ A S M _ O F F S E T & 0xff ]
2006-04-02 20:46:25 +04:00
@ Restore regs and return
2005-09-07 20:20:26 +04:00
ldmfd s p ! , { r0 - r12 , p c }
2005-07-10 22:58:15 +04:00
ENTRY( o m a p16 1 0 _ c p u _ s u s p e n d _ s z )
.word . - omap1 6 1 0 _ c p u _ s u s p e n d
# endif / * C O N F I G _ A R C H _ O M A P 1 6 X X * /