2012-01-26 18:22:02 +02:00
/ *
* arch/ a r m / m a c h - t e g r a / s l e e p . S
*
* Copyright ( c ) 2 0 1 0 - 2 0 1 1 , N V I D I A C o r p o r a t i o n .
* Copyright ( c ) 2 0 1 1 , G o o g l e , I n c .
*
* Author : Colin C r o s s < c c r o s s @android.com>
* Gary K i n g < g k i n g @nvidia.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 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 p u b l i s h e d b y
* the 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 License, or
* ( at 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 , b u t W I T H O U T
* ANY W A R R A N T Y ; without even the implied warranty of MERCHANTABILITY or
* FITNESS 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 G N U G e n e r a l P u b l i c L i c e n s e f o r
* more 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 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.,
* 5 1 Franklin S t r e e t , F i f t h F l o o r , B o s t o n , M A 0 2 1 1 0 - 1 3 0 1 , U S A .
* /
# include < l i n u x / l i n k a g e . h >
2012-03-19 09:55:12 -06:00
# include < a s m / a s s e m b l e r . h >
2012-10-31 17:41:21 +08:00
# include < a s m / c a c h e . h >
2012-10-31 17:41:17 +08:00
# include < a s m / c p15 . h >
2012-11-13 10:04:48 +08:00
# include < a s m / h a r d w a r e / c a c h e - l 2 x0 . h >
2012-03-19 09:55:12 -06:00
2012-10-04 14:24:09 -06:00
# include " i o m a p . h "
2012-01-26 18:22:02 +02:00
# include " f l o w c t r l . h "
2012-08-16 17:31:50 +08:00
# include " s l e e p . h "
2012-01-26 18:22:02 +02:00
2013-01-16 17:33:55 +00:00
# define C L K _ R E S E T _ C C L K _ B U R S T 0 x20
# define C L K _ R E S E T _ C C L K _ D I V I D E R 0 x24
2013-01-03 14:42:59 +08:00
# if d e f i n e d ( C O N F I G _ H O T P L U G _ C P U ) | | d e f i n e d ( C O N F I G _ P M _ S L E E P )
2012-10-31 17:41:17 +08:00
/ *
* tegra_ d i s a b l e _ c l e a n _ i n v _ d c a c h e
*
* disable, c l e a n & i n v a l i d a t e t h e D - c a c h e
*
* Corrupted r e g i s t e r s : r1 - r3 , r6 , r8 , r9 - r11
* /
ENTRY( t e g r a _ d i s a b l e _ c l e a n _ i n v _ d c a c h e )
stmfd s p ! , { r0 , r4 - r5 , r7 , r9 - r11 , l r }
dmb @ ensure ordering
/* Disable the D-cache */
mrc p15 , 0 , r2 , c1 , c0 , 0
bic r2 , r2 , #C R _ C
mcr p15 , 0 , r2 , c1 , c0 , 0
isb
/* Flush the D-cache */
2013-07-03 17:50:38 +08:00
cmp r0 , #T E G R A _ F L U S H _ C A C H E _ A L L
blne v7 _ f l u s h _ d c a c h e _ l o u i s
bleq v7 _ f l u s h _ d c a c h e _ a l l
2012-10-31 17:41:17 +08:00
/* Trun off coherency */
exit_ s m p r4 , r5
ldmfd s p ! , { r0 , r4 - r5 , r7 , r9 - r11 , p c }
ENDPROC( t e g r a _ d i s a b l e _ c l e a n _ i n v _ d c a c h e )
2013-01-03 14:42:59 +08:00
# endif
2012-10-31 17:41:17 +08:00
2013-01-03 14:42:59 +08:00
# ifdef C O N F I G _ P M _ S L E E P
2013-07-03 17:50:39 +08:00
/ *
* tegra_ i n i t _ l 2 _ f o r _ a15
*
* set u p t h e c o r r e c t L 2 c a c h e d a t a R A M l a t e n c y
* /
ENTRY( t e g r a _ i n i t _ l 2 _ f o r _ a15 )
mrc p15 , 0 , r0 , c0 , c0 , 5
ubfx r0 , r0 , #8 , #4
tst r0 , #1 @ only need for cluster 0
bne _ e x i t _ i n i t _ l 2 _ a15
mrc p15 , 0 x1 , r0 , c9 , c0 , 2
and r0 , r0 , #7
cmp r0 , #2
bicne r0 , r0 , #7
orrne r0 , r0 , #2
mcrne p15 , 0 x1 , r0 , c9 , c0 , 2
_exit_init_l2_a15 :
mov p c , l r
ENDPROC( t e g r a _ i n i t _ l 2 _ f o r _ a15 )
2012-10-31 17:41:21 +08:00
/ *
* tegra_ s l e e p _ c p u _ f i n i s h ( u n s i g n e d l o n g v2 p )
*
* enters s u s p e n d i n L P 2 b y t u r n i n g o f f t h e m m u a n d j u m p i n g t o
* tegra? _ t e a r _ d o w n _ c p u
* /
ENTRY( t e g r a _ s l e e p _ c p u _ f i n i s h )
2013-07-03 17:50:38 +08:00
mov r4 , r0
2012-10-31 17:41:21 +08:00
/* Flush and disable the L1 data cache */
2013-07-03 17:50:38 +08:00
mov r0 , #T E G R A _ F L U S H _ C A C H E _ A L L
2012-10-31 17:41:21 +08:00
bl t e g r a _ d i s a b l e _ c l e a n _ i n v _ d c a c h e
2013-07-03 17:50:38 +08:00
mov r0 , r4
2012-10-31 17:41:21 +08:00
mov3 2 r6 , t e g r a _ t e a r _ d o w n _ c p u
ldr r1 , [ r6 ]
add r1 , r1 , r0
mov3 2 r3 , t e g r a _ s h u t _ o f f _ m m u
add r3 , r3 , r0
mov r0 , r1
mov p c , r3
ENDPROC( t e g r a _ s l e e p _ c p u _ f i n i s h )
/ *
* tegra_ s h u t _ o f f _ m m u
*
* r0 = p h y s i c a l a d d r e s s t o j u m p t o w i t h m m u o f f
*
* called w i t h V A =PA m a p p i n g
* turns o f f M M U , i c a c h e , d c a c h e a n d b r a n c h p r e d i c t i o n
* /
.align L1_CACHE_SHIFT
.pushsection .idmap .text , " ax"
ENTRY( t e g r a _ s h u t _ o f f _ m m u )
mrc p15 , 0 , r3 , c1 , c0 , 0
movw r2 , #C R _ I | C R _ Z | C R _ C | C R _ M
bic r3 , r3 , r2
dsb
mcr p15 , 0 , r3 , c1 , c0 , 0
isb
2012-11-13 10:04:48 +08:00
# ifdef C O N F I G _ C A C H E _ L 2 X 0
/* Disable L2 cache */
2013-05-20 18:39:25 +08:00
check_ c p u _ p a r t _ n u m 0 x c09 , r9 , r10
ARM: tegra: add LP1 suspend support for Tegra30
The LP1 suspend mode will power off the CPU, clock gated the PLLs and put
SDRAM to self-refresh mode. Any interrupt can wake up device from LP1. The
sequence when LP1 suspending:
* tunning off L1 data cache and the MMU
* storing some EMC registers, DPD (deep power down) status, clk source of
mselect and SCLK burst policy
* putting SDRAM into self-refresh
* switching CPU to CLK_M (12MHz OSC)
* tunning off PLLM, PLLP, PLLA, PLLC and PLLX
* switching SCLK to CLK_S (32KHz OSC)
* shutting off the CPU rail
The sequence of LP1 resuming:
* re-enabling PLLM, PLLP, PLLA, PLLC and PLLX
* restoring the clk source of mselect and SCLK burst policy
* setting up CCLK burst policy to PLLX
* restoring DPD status and some EMC registers
* resuming SDRAM to normal mode
* jumping to the "tegra_resume" from PMC_SCRATCH41
Due to the SDRAM will be put into self-refresh mode, the low level
procedures of LP1 suspending and resuming should be copied to
TEGRA_IRAM_CODE_AREA (TEGRA_IRAM_BASE + SZ_4K) when suspending. Before
restoring the CPU context when resuming, the SDRAM needs to be switched
back to normal mode. And the PLLs need to be re-enabled, SCLK burst policy
be restored, CCLK burst policy be set in PLLX. Then jumping to
"tegra_resume" that was expected to be stored in PMC_SCRATCH41 to restore
CPU context and back to kernel.
Based on the work by: Scott Williams <scwilliams@nvidia.com>
Signed-off-by: Joseph Lo <josephl@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-08-12 17:40:04 +08:00
movweq r2 , #: l o w e r 16 : ( T E G R A _ A R M _ P E R I F _ B A S E + 0 x30 0 0 )
movteq r2 , #: u p p e r 16 : ( T E G R A _ A R M _ P E R I F _ B A S E + 0 x30 0 0 )
moveq r3 , #0
streq r3 , [ r2 , #L 2 X 0 _ C T R L ]
2012-11-13 10:04:48 +08:00
# endif
2012-10-31 17:41:21 +08:00
mov p c , r0
ENDPROC( t e g r a _ s h u t _ o f f _ m m u )
.popsection
2013-01-16 17:33:55 +00:00
/ *
* tegra_ s w i t c h _ c p u _ t o _ p l l p
*
* In L P 2 t h e n o r m a l c p u c l o c k p l l x w i l l b e t u r n e d o f f . S w i t c h t h e C P U t o p l l p
* /
ENTRY( t e g r a _ s w i t c h _ c p u _ t o _ p l l p )
/* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */
mov3 2 r5 , T E G R A _ C L K _ R E S E T _ B A S E
mov r0 , #( 2 < < 2 8 ) @ burst policy = run mode
orr r0 , r0 , #( 4 < < 4 ) @ use PLLP in run mode burst
str r0 , [ r5 , #C L K _ R E S E T _ C C L K _ B U R S T ]
mov r0 , #0
str r0 , [ r5 , #C L K _ R E S E T _ C C L K _ D I V I D E R ]
mov p c , l r
ENDPROC( t e g r a _ s w i t c h _ c p u _ t o _ p l l p )
2012-10-31 17:41:17 +08:00
# endif