2019-05-19 15:51:31 +02:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
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>
* /
# 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-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
2019-03-18 01:52:10 +03:00
tst r2 , #C R _ C @ s e e t e g r a _ s l e e p _ c p u ( )
2012-10-31 17:41:17 +08:00
bic r2 , r2 , #C R _ C
2019-03-18 01:52:10 +03:00
mcrne p15 , 0 , r2 , c1 , c0 , 0
2012-10-31 17:41:17 +08:00
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 :
2014-06-30 16:29:12 +01:00
ret l r
2013-07-03 17:50:39 +08:00
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
2014-06-30 16:29:12 +01:00
ret r3
2012-10-31 17:41:21 +08:00
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
2019-03-18 01:52:10 +03:00
retne r0
mov3 2 r2 , T E G R A _ A R M _ P E R I F _ B A S E + 0 x30 0 0
ldr r3 , [ r2 , #L 2 X 0 _ C T R L ]
tst r3 , #L 2 X 0 _ C T R L _ E N @ see tegra_sleep_cpu()
mov r3 , #0
strne r3 , [ r2 , #L 2 X 0 _ C T R L ]
2012-11-13 10:04:48 +08:00
# endif
2014-06-30 16:29:12 +01:00
ret r0
2012-10-31 17:41:21 +08:00
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 ]
2014-06-30 16:29:12 +01:00
ret l r
2013-01-16 17:33:55 +00:00
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