2019-06-04 10:11:33 +02:00
/* SPDX-License-Identifier: GPL-2.0-only */
2008-09-21 21:35:18 +01:00
/ *
* arch/ a r m / m a c h - a t 9 1 / p m _ s l o w _ c l o c k . S
*
* Copyright ( C ) 2 0 0 6 S a v i n Z l o b e c
*
* AT9 1 S A M 9 s u p p o r t :
2017-03-28 12:26:18 +02:00
* Copyright ( C ) 2 0 0 7 A n t i S u l l i n < a n t i . s u l l i n @artecdesign.ee>
2008-09-21 21:35:18 +01:00
* /
# include < l i n u x / l i n k a g e . h >
2013-10-11 09:37:45 +02:00
# include < l i n u x / c l k / a t 9 1 _ p m c . h >
2015-03-09 11:49:46 +08:00
# include " p m . h "
ARM: at91: move platform-specific asm-offset.h to arch/arm/mach-at91
<generated/at91_pm_data-offsets.h> is only generated and included by
arch/arm/mach-at91/, so it does not need to reside in the globally
visible include/generated/.
I renamed it to arch/arm/mach-at91/pm_data-offsets.h since the prefix
'at91_' is just redundant in mach-at91/.
My main motivation of this change is to avoid the race condition for
the parallel build (-j) when CONFIG_IKHEADERS is enabled.
When it is enabled, all the headers under include/ are archived into
kernel/kheaders_data.tar.xz and exposed in the sysfs.
In the parallel build, we have no idea in which order files are built.
- If at91_pm_data-offsets.h is built before kheaders_data.tar.xz,
the header will be included in the archive. Probably nobody will
use it, but it is harmless except that it will increase the archive
size needlessly.
- If kheaders_data.tar.xz is built before at91_pm_data-offsets.h,
the header will not be included in the archive. However, in the next
build, the archive will be re-generated to include the newly-found
at91_pm_data-offsets.h. This is not nice from the build system point
of view.
- If at91_pm_data-offsets.h and kheaders_data.tar.xz are built at the
same time, the corrupted header might be included in the archive,
which does not look nice either.
This commit fixes the race.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Link: https://lore.kernel.org/r/20190823024346.591-1-yamada.masahiro@socionext.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2019-08-23 11:43:45 +09:00
# include " p m _ d a t a - o f f s e t s . h "
2008-09-21 21:35:18 +01:00
2015-03-09 11:48:26 +08:00
# define S R A M C _ S E L F _ F R E S H _ A C T I V E 0 x01
# define S R A M C _ S E L F _ F R E S H _ E X I T 0 x00
2012-02-22 17:50:54 +01:00
pmc . r e q r0
2012-02-22 17:50:55 +01:00
tmp1 . r e q r4
tmp2 . r e q r5
2020-01-20 14:10:07 +02:00
tmp3 . r e q r6
2008-09-21 21:35:18 +01:00
/ *
* Wait u n t i l m a s t e r c l o c k i s r e a d y ( a f t e r s w i t c h i n g m a s t e r c l o c k s o u r c e )
* /
.macro wait_mckrdy
2015-02-05 14:00:37 +08:00
1 : ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
2012-02-22 17:50:53 +01:00
tst t m p1 , #A T 91 _ P M C _ M C K R D Y
2008-09-21 21:35:18 +01:00
beq 1 b
.endm
/ *
* Wait u n t i l m a s t e r o s c i l l a t o r h a s s t a b i l i z e d .
* /
.macro wait_moscrdy
2015-02-05 14:00:37 +08:00
1 : ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
2012-02-22 17:50:53 +01:00
tst t m p1 , #A T 91 _ P M C _ M O S C S
2008-09-21 21:35:18 +01:00
beq 1 b
.endm
2018-07-17 11:26:55 +03:00
/ *
* Wait f o r m a i n o s c i l l a t o r s e l e c t i o n i s d o n e
* /
.macro wait_moscsels
1 : ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
tst t m p1 , #A T 91 _ P M C _ M O S C S E L S
beq 1 b
.endm
2015-03-09 11:53:46 +08:00
/ *
* Put t h e p r o c e s s o r t o e n t e r t h e i d l e s t a t e
* /
.macro at91_cpu_idle
# if d e f i n e d ( C O N F I G _ C P U _ V 7 )
mov t m p1 , #A T 91 _ P M C _ P C K
str t m p1 , [ p m c , #A T 91 _ P M C _ S C D R ]
dsb
wfi @ Wait For Interrupt
# else
mcr p15 , 0 , t m p1 , c7 , c0 , 4
# endif
.endm
2008-09-21 21:35:18 +01:00
.text
2015-03-11 10:08:12 +08:00
.arm
2015-03-09 11:51:09 +08:00
/ *
2017-01-31 18:12:57 +01:00
* void a t 9 1 _ s u s p e n d _ s r a m _ f n ( s t r u c t a t 9 1 _ p m _ d a t a * )
2015-03-09 11:51:09 +08:00
* @input param:
2017-01-31 18:12:57 +01:00
* @r0: base address of struct at91_pm_data
2012-02-22 17:50:55 +01:00
* /
2015-10-16 12:39:05 +02:00
/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
.align 3
2015-03-09 11:51:09 +08:00
ENTRY( a t 9 1 _ p m _ s u s p e n d _ i n _ s r a m )
2008-09-21 21:35:18 +01:00
/* Save registers on stack */
2012-02-22 17:50:55 +01:00
stmfd s p ! , { r4 - r12 , l r }
2008-09-21 21:35:18 +01:00
/* Drain write buffer */
2012-02-22 17:50:53 +01:00
mov t m p1 , #0
mcr p15 , 0 , t m p1 , c7 , c10 , 4
2008-09-21 21:35:18 +01:00
2017-01-31 18:12:57 +01:00
ldr t m p1 , [ r0 , #P M _ D A T A _ P M C ]
str t m p1 , . p m c _ b a s e
ldr t m p1 , [ r0 , #P M _ D A T A _ R A M C 0 ]
str t m p1 , . s r a m c _ b a s e
ldr t m p1 , [ r0 , #P M _ D A T A _ R A M C 1 ]
str t m p1 , . s r a m c1 _ b a s e
ldr t m p1 , [ r0 , #P M _ D A T A _ M E M C T R L ]
str t m p1 , . m e m t y p e
ldr t m p1 , [ r0 , #P M _ D A T A _ M O D E ]
str t m p1 , . p m _ m o d e
2020-01-20 14:10:01 +02:00
ldr t m p1 , [ r0 , #P M _ D A T A _ P M C _ M C K R _ O F F S E T ]
str t m p1 , . m c k r _ o f f s e t
2020-01-20 14:10:04 +02:00
ldr t m p1 , [ r0 , #P M _ D A T A _ P M C _ V E R S I O N ]
str t m p1 , . p m c _ v e r s i o n
2016-09-27 12:29:50 +02:00
/* Both ldrne below are here to preload their address in the TLB */
ldr t m p1 , [ r0 , #P M _ D A T A _ S H D W C ]
str t m p1 , . s h d w c
cmp t m p1 , #0
ldrne t m p2 , [ t m p1 , #0 ]
ldr t m p1 , [ r0 , #P M _ D A T A _ S F R B U ]
2020-01-20 14:10:05 +02:00
str t m p1 , . s f r b u
2016-09-27 12:29:50 +02:00
cmp t m p1 , #0
ldrne t m p2 , [ t m p1 , #0x10 ]
2012-02-22 17:50:55 +01:00
2015-03-09 11:48:26 +08:00
/* Active the self-refresh mode */
mov r0 , #S R A M C _ S E L F _ F R E S H _ A C T I V E
bl a t 9 1 _ s r a m c _ s e l f _ r e f r e s h
2012-02-22 17:50:55 +01:00
2015-03-09 11:49:46 +08:00
ldr r0 , . p m _ m o d e
2018-07-17 11:26:55 +03:00
cmp r0 , #A T 91 _ P M _ S T A N D B Y
beq s t a n d b y
2016-09-27 12:29:50 +02:00
cmp r0 , #A T 91 _ P M _ B A C K U P
beq b a c k u p _ m o d e
2015-03-09 11:49:46 +08:00
2018-07-17 11:26:55 +03:00
bl a t 9 1 _ u l p _ m o d e
b e x i t _ s u s p e n d
standby :
2016-09-27 12:29:50 +02:00
/* Wait for interrupt */
ldr p m c , . p m c _ b a s e
at9 1 _ c p u _ i d l e
b e x i t _ s u s p e n d
backup_mode :
bl a t 9 1 _ b a c k u p _ m o d e
b e x i t _ s u s p e n d
exit_suspend :
/* Exit the self-refresh mode */
mov r0 , #S R A M C _ S E L F _ F R E S H _ E X I T
bl a t 9 1 _ s r a m c _ s e l f _ r e f r e s h
/* Restore registers, and return */
ldmfd s p ! , { r4 - r12 , p c }
ENDPROC( a t 9 1 _ p m _ s u s p e n d _ i n _ s r a m )
ENTRY( a t 9 1 _ b a c k u p _ m o d e )
2018-08-30 14:50:06 +03:00
/* Switch the master clock source to slow clock. */
ldr p m c , . p m c _ b a s e
2020-01-20 14:10:01 +02:00
ldr t m p2 , . m c k r _ o f f s e t
ldr t m p1 , [ p m c , t m p2 ]
2018-08-30 14:50:06 +03:00
bic t m p1 , t m p1 , #A T 91 _ P M C _ C S S
2020-01-20 14:10:01 +02:00
str t m p1 , [ p m c , t m p2 ]
2018-08-30 14:50:06 +03:00
wait_ m c k r d y
2016-09-27 12:29:50 +02:00
/*BUMEN*/
2020-01-20 14:10:05 +02:00
ldr r0 , . s f r b u
2016-09-27 12:29:50 +02:00
mov t m p1 , #0x1
str t m p1 , [ r0 , #0x10 ]
/* Shutdown */
ldr r0 , . s h d w c
mov t m p1 , #0xA5000000
add t m p1 , t m p1 , #0x1
str t m p1 , [ r0 , #0 ]
ENDPROC( a t 9 1 _ b a c k u p _ m o d e )
2018-07-17 11:26:55 +03:00
.macro at91_pm_ulp0_mode
ldr p m c , . p m c _ b a s e
/* Turn off the crystal oscillator */
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
bic t m p1 , t m p1 , #A T 91 _ P M C _ M O S C E N
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
2019-02-14 15:55:01 +00:00
/* Save RC oscillator state */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
str t m p1 , . s a v e d _ o s c _ s t a t u s
tst t m p1 , #A T 91 _ P M C _ M O S C R C S
bne 1 f
/* Turn off RC oscillator */
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
bic t m p1 , t m p1 , #A T 91 _ P M C _ M O S C R C E N
bic t m p1 , t m p1 , #A T 91 _ P M C _ K E Y _ M A S K
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
/* Wait main RC disabled done */
2 : ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
tst t m p1 , #A T 91 _ P M C _ M O S C R C S
bne 2 b
2018-07-17 11:26:55 +03:00
/* Wait for interrupt */
2019-02-14 15:55:01 +00:00
1 : at9 1 _ c p u _ i d l e
2018-07-17 11:26:55 +03:00
2019-02-14 15:55:01 +00:00
/* Restore RC oscillator state */
ldr t m p1 , . s a v e d _ o s c _ s t a t u s
tst t m p1 , #A T 91 _ P M C _ M O S C R C S
beq 4 f
/* Turn on RC oscillator */
2018-07-17 11:26:55 +03:00
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
2019-02-14 15:55:01 +00:00
orr t m p1 , t m p1 , #A T 91 _ P M C _ M O S C R C E N
bic t m p1 , t m p1 , #A T 91 _ P M C _ K E Y _ M A S K
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
/* Wait main RC stabilization */
3 : ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
tst t m p1 , #A T 91 _ P M C _ M O S C R C S
beq 3 b
/* Turn on the crystal oscillator */
4 : ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
2018-07-17 11:26:55 +03:00
orr t m p1 , t m p1 , #A T 91 _ P M C _ M O S C E N
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
wait_ m o s c r d y
.endm
/ * *
* Note : This p r o c e d u r e o n l y a p p l i e s o n t h e p l a t f o r m w h i c h u s e s
* the e x t e r n a l c r y s t a l o s c i l l a t o r a s a m a i n c l o c k s o u r c e .
* /
.macro at91_pm_ulp1_mode
ldr p m c , . p m c _ b a s e
2020-01-20 14:10:01 +02:00
ldr t m p2 , . m c k r _ o f f s e t
2018-07-17 11:26:55 +03:00
2019-02-14 15:54:57 +00:00
/* Save RC oscillator state and check if it is enabled. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
str t m p1 , . s a v e d _ o s c _ s t a t u s
tst t m p1 , #A T 91 _ P M C _ M O S C R C S
bne 2 f
/* Enable RC oscillator */
2018-07-17 11:26:55 +03:00
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
2019-02-14 15:54:57 +00:00
orr t m p1 , t m p1 , #A T 91 _ P M C _ M O S C R C E N
bic t m p1 , t m p1 , #A T 91 _ P M C _ K E Y _ M A S K
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
/* Wait main RC stabilization */
1 : ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
tst t m p1 , #A T 91 _ P M C _ M O S C R C S
beq 1 b
/* Switch the main clock source to 12-MHz RC oscillator */
2 : ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
2018-07-17 11:26:55 +03:00
bic t m p1 , t m p1 , #A T 91 _ P M C _ M O S C S E L
bic t m p1 , t m p1 , #A T 91 _ P M C _ K E Y _ M A S K
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
wait_ m o s c s e l s
/* Disable the crystal oscillator */
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
bic t m p1 , t m p1 , #A T 91 _ P M C _ M O S C E N
bic t m p1 , t m p1 , #A T 91 _ P M C _ K E Y _ M A S K
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
/* Switch the master clock source to main clock */
2020-01-20 14:10:01 +02:00
ldr t m p1 , [ p m c , t m p2 ]
2018-07-17 11:26:55 +03:00
bic t m p1 , t m p1 , #A T 91 _ P M C _ C S S
orr t m p1 , t m p1 , #A T 91 _ P M C _ C S S _ M A I N
2020-01-20 14:10:01 +02:00
str t m p1 , [ p m c , t m p2 ]
2018-07-17 11:26:55 +03:00
wait_ m c k r d y
/* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
orr t m p1 , t m p1 , #A T 91 _ P M C _ W A I T M O D E
bic t m p1 , t m p1 , #A T 91 _ P M C _ K E Y _ M A S K
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
2020-01-20 14:10:08 +02:00
/* Quirk for SAM9X60's PMC */
nop
nop
2018-07-17 11:26:55 +03:00
wait_ m c k r d y
/* Enable the crystal oscillator */
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
orr t m p1 , t m p1 , #A T 91 _ P M C _ M O S C E N
bic t m p1 , t m p1 , #A T 91 _ P M C _ K E Y _ M A S K
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
wait_ m o s c r d y
/* Switch the master clock source to slow clock */
2020-01-20 14:10:01 +02:00
ldr t m p1 , [ p m c , t m p2 ]
2018-07-17 11:26:55 +03:00
bic t m p1 , t m p1 , #A T 91 _ P M C _ C S S
2020-01-20 14:10:01 +02:00
str t m p1 , [ p m c , t m p2 ]
2018-07-17 11:26:55 +03:00
wait_ m c k r d y
/* Switch main clock source to crystal oscillator */
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
orr t m p1 , t m p1 , #A T 91 _ P M C _ M O S C S E L
bic t m p1 , t m p1 , #A T 91 _ P M C _ K E Y _ M A S K
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
wait_ m o s c s e l s
/* Switch the master clock source to main clock */
2020-01-20 14:10:01 +02:00
ldr t m p1 , [ p m c , t m p2 ]
2018-07-17 11:26:55 +03:00
bic t m p1 , t m p1 , #A T 91 _ P M C _ C S S
orr t m p1 , t m p1 , #A T 91 _ P M C _ C S S _ M A I N
2020-01-20 14:10:01 +02:00
str t m p1 , [ p m c , t m p2 ]
2018-07-17 11:26:55 +03:00
wait_ m c k r d y
2019-02-14 15:54:57 +00:00
/* Restore RC oscillator state */
ldr t m p1 , . s a v e d _ o s c _ s t a t u s
tst t m p1 , #A T 91 _ P M C _ M O S C R C S
bne 3 f
/* Disable RC oscillator */
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
bic t m p1 , t m p1 , #A T 91 _ P M C _ M O S C R C E N
bic t m p1 , t m p1 , #A T 91 _ P M C _ K E Y _ M A S K
orr t m p1 , t m p1 , #A T 91 _ P M C _ K E Y
str t m p1 , [ p m c , #A T 91 _ C K G R _ M O R ]
/* Wait RC oscillator disable done */
4 : ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
tst t m p1 , #A T 91 _ P M C _ M O S C R C S
bne 4 b
3 :
2018-07-17 11:26:55 +03:00
.endm
2020-01-20 14:10:03 +02:00
.macro at91_plla_disable
/* Save PLLA setting and disable it */
2020-01-20 14:10:07 +02:00
ldr t m p1 , . p m c _ v e r s i o n
cmp t m p1 , #A T 91 _ P M C _ V 1
beq 1 f
# ifdef C O N F I G _ S O C _ S A M 9 X 6 0
/* Save PLLA settings. */
ldr t m p2 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
bic t m p2 , t m p2 , #A T 91 _ P M C _ P L L _ U P D T _ I D
str t m p2 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
/* save div. */
mov t m p1 , #0
ldr t m p2 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 0 ]
bic t m p2 , t m p2 , #0xffffff00
orr t m p1 , t m p1 , t m p2
/* save mul. */
ldr t m p2 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 1 ]
bic t m p2 , t m p2 , #0xffffff
orr t m p1 , t m p1 , t m p2
str t m p1 , . s a v e d _ p l l a r
/* step 2. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ U P D A T E
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ I D
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
/* step 3. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 0 ]
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ C T R L 0 _ E N P L L C K
orr t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ C T R L 0 _ E N P L L
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 0 ]
/* step 4. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
orr t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ U P D A T E
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ I D
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
/* step 5. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 0 ]
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ C T R L 0 _ E N P L L
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 0 ]
/* step 7. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
orr t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ U P D A T E
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ I D
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
b 2 f
# endif
1 : /* Save PLLA setting and disable it */
2020-01-20 14:10:03 +02:00
ldr t m p1 , [ p m c , #A T 91 _ C K G R _ P L L A R ]
str t m p1 , . s a v e d _ p l l a r
/* Disable PLLA. */
mov t m p1 , #A T 91 _ P M C _ P L L C O U N T
orr t m p1 , t m p1 , #( 1 < < 2 9 ) / * b i t 2 9 a l w a y s s e t * /
str t m p1 , [ p m c , #A T 91 _ C K G R _ P L L A R ]
2020-01-20 14:10:07 +02:00
2 :
2020-01-20 14:10:03 +02:00
.endm
.macro at91_plla_enable
2020-01-20 14:10:07 +02:00
ldr t m p2 , . s a v e d _ p l l a r
ldr t m p3 , . p m c _ v e r s i o n
cmp t m p3 , #A T 91 _ P M C _ V 1
beq 4 f
# ifdef C O N F I G _ S O C _ S A M 9 X 6 0
/* step 1. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ I D
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ U P D A T E
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
/* step 2. */
ldr t m p1 , = #A T 91 _ P M C _ P L L _ A C R _ D E F A U L T _ P L L A
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ A C R ]
/* step 3. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 1 ]
mov t m p3 , t m p2
bic t m p3 , t m p3 , #0xffffff
orr t m p1 , t m p1 , t m p3
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 1 ]
/* step 8. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ I D
orr t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ U P D A T E
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
/* step 9. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 0 ]
orr t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ C T R L 0 _ E N L O C K
orr t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ C T R L 0 _ E N P L L
orr t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ C T R L 0 _ E N P L L C K
bic t m p1 , t m p1 , #0xff
mov t m p3 , t m p2
bic t m p3 , t m p3 , #0xffffff00
orr t m p1 , t m p1 , t m p3
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ C T R L 0 ]
/* step 10. */
ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
orr t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ U P D A T E
bic t m p1 , t m p1 , #A T 91 _ P M C _ P L L _ U P D T _ I D
str t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ U P D T ]
/* step 11. */
3 : ldr t m p1 , [ p m c , #A T 91 _ P M C _ P L L _ I S R 0 ]
tst t m p1 , #0x1
beq 3 b
b 2 f
# endif
2020-01-20 14:10:03 +02:00
/* Restore PLLA setting */
2020-01-20 14:10:07 +02:00
4 : str t m p2 , [ p m c , #A T 91 _ C K G R _ P L L A R ]
2020-01-20 14:10:03 +02:00
/* Enable PLLA. */
2020-01-20 14:10:07 +02:00
tst t m p2 , #( A T 91 _ P M C _ M U L & 0 x f f00 0 0 )
2020-01-20 14:10:03 +02:00
bne 1 f
2020-01-20 14:10:07 +02:00
tst t m p2 , #( A T 91 _ P M C _ M U L & ~ 0 x f f00 0 0 )
2020-01-20 14:10:03 +02:00
beq 2 f
1 : ldr t m p1 , [ p m c , #A T 91 _ P M C _ S R ]
tst t m p1 , #A T 91 _ P M C _ L O C K A
beq 1 b
2 :
.endm
2018-07-17 11:26:55 +03:00
ENTRY( a t 9 1 _ u l p _ m o d e )
2015-03-09 11:48:26 +08:00
ldr p m c , . p m c _ b a s e
2020-01-20 14:10:01 +02:00
ldr t m p2 , . m c k r _ o f f s e t
2008-09-21 21:35:18 +01:00
/* Save Master clock setting */
2020-01-20 14:10:01 +02:00
ldr t m p1 , [ p m c , t m p2 ]
2012-02-22 17:50:53 +01:00
str t m p1 , . s a v e d _ m c k r
2008-09-21 21:35:18 +01:00
/ *
* Set t h e M a s t e r c l o c k s o u r c e t o s l o w c l o c k
* /
2012-02-22 17:50:53 +01:00
bic t m p1 , t m p1 , #A T 91 _ P M C _ C S S
2020-01-20 14:10:01 +02:00
str t m p1 , [ p m c , t m p2 ]
2008-09-21 21:35:18 +01:00
wait_ m c k r d y
2020-01-20 14:10:03 +02:00
at9 1 _ p l l a _ d i s a b l e
2020-01-20 14:10:02 +02:00
2018-07-17 11:26:55 +03:00
ldr r0 , . p m _ m o d e
cmp r0 , #A T 91 _ P M _ U L P 1
beq u l p1 _ m o d e
2008-09-21 21:35:18 +01:00
2018-07-17 11:26:55 +03:00
at9 1 _ p m _ u l p0 _ m o d e
b u l p _ e x i t
2008-09-21 21:35:18 +01:00
2018-07-17 11:26:55 +03:00
ulp1_mode :
at9 1 _ p m _ u l p1 _ m o d e
b u l p _ e x i t
2008-09-21 21:35:18 +01:00
2018-07-17 11:26:55 +03:00
ulp_exit :
ldr p m c , . p m c _ b a s e
2008-09-21 21:35:18 +01:00
2020-01-20 14:10:03 +02:00
at9 1 _ p l l a _ e n a b l e
2020-01-20 14:10:02 +02:00
2008-09-21 21:35:18 +01:00
/ *
* Restore m a s t e r c l o c k s e t t i n g
* /
2020-01-20 14:10:01 +02:00
ldr t m p1 , . m c k r _ o f f s e t
ldr t m p2 , . s a v e d _ m c k r
str t m p2 , [ p m c , t m p1 ]
2008-09-21 21:35:18 +01:00
wait_ m c k r d y
2016-09-27 12:29:50 +02:00
mov p c , l r
2018-07-17 11:26:55 +03:00
ENDPROC( a t 9 1 _ u l p _ m o d e )
2015-03-09 11:48:26 +08:00
/ *
* void a t 9 1 _ s r a m c _ s e l f _ r e f r e s h ( u n s i g n e d i n t i s _ a c t i v e )
*
* @input param:
* @r0: 1 - active self-refresh mode
* 0 - exit s e l f - r e f r e s h m o d e
* register u s a g e :
* @r1: memory type
* @r2: base address of the sram controller
* /
ENTRY( a t 9 1 _ s r a m c _ s e l f _ r e f r e s h )
ldr r1 , . m e m t y p e
ldr r2 , . s r a m c _ b a s e
cmp r1 , #A T 91 _ M E M C T R L _ M C
bne d d r c _ s f
2012-02-22 17:50:55 +01:00
/ *
* at9 1 r m 9 2 0 0 M e m o r y c o n t r o l l e r
* /
2015-03-09 11:48:26 +08:00
/ *
* For e x i t i n g t h e s e l f - r e f r e s h m o d e , d o n o t h i n g ,
* automatically e x i t t h e s e l f - r e f r e s h m o d e .
* /
tst r0 , #S R A M C _ S E L F _ F R E S H _ A C T I V E
beq e x i t _ s r a m c _ s f
/* Active SDRAM self-refresh mode */
mov r3 , #1
2015-03-16 15:14:50 +01:00
str r3 , [ r2 , #A T 91 _ M C _ S D R A M C _ S R R ]
2015-03-09 11:48:26 +08:00
b e x i t _ s r a m c _ s f
ddrc_sf :
cmp r1 , #A T 91 _ M E M C T R L _ D D R S D R
bne s d r a m c _ s f
2012-02-22 17:50:55 +01:00
/ *
2015-03-09 11:48:26 +08:00
* DDR M e m o r y c o n t r o l l e r
2012-02-22 17:50:55 +01:00
* /
2015-03-09 11:48:26 +08:00
tst r0 , #S R A M C _ S E L F _ F R E S H _ A C T I V E
beq d d r c _ e x i t _ s f
/* LPDDR1 --> force DDR2 mode during self-refresh */
ldr r3 , [ r2 , #A T 91 _ D D R S D R C _ M D R ]
str r3 , . s a v e d _ s a m 9 _ m d r
bic r3 , r3 , #~ A T 91 _ D D R S D R C _ M D
cmp r3 , #A T 91 _ D D R S D R C _ M D _ L O W _ P O W E R _ D D R
ldreq r3 , [ r2 , #A T 91 _ D D R S D R C _ M D R ]
biceq r3 , r3 , #A T 91 _ D D R S D R C _ M D
orreq r3 , r3 , #A T 91 _ D D R S D R C _ M D _ D D R 2
streq r3 , [ r2 , #A T 91 _ D D R S D R C _ M D R ]
/* Active DDRC self-refresh mode */
ldr r3 , [ r2 , #A T 91 _ D D R S D R C _ L P R ]
str r3 , . s a v e d _ s a m 9 _ l p r
bic r3 , r3 , #A T 91 _ D D R S D R C _ L P C B
orr r3 , r3 , #A T 91 _ D D R S D R C _ L P C B _ S E L F _ R E F R E S H
str r3 , [ r2 , #A T 91 _ D D R S D R C _ L P R ]
/* If using the 2nd ddr controller */
ldr r2 , . s r a m c1 _ b a s e
cmp r2 , #0
beq n o _ 2 n d _ d d r c
ldr r3 , [ r2 , #A T 91 _ D D R S D R C _ M D R ]
str r3 , . s a v e d _ s a m 9 _ m d r1
bic r3 , r3 , #~ A T 91 _ D D R S D R C _ M D
cmp r3 , #A T 91 _ D D R S D R C _ M D _ L O W _ P O W E R _ D D R
ldreq r3 , [ r2 , #A T 91 _ D D R S D R C _ M D R ]
biceq r3 , r3 , #A T 91 _ D D R S D R C _ M D
orreq r3 , r3 , #A T 91 _ D D R S D R C _ M D _ D D R 2
streq r3 , [ r2 , #A T 91 _ D D R S D R C _ M D R ]
/* Active DDRC self-refresh mode */
ldr r3 , [ r2 , #A T 91 _ D D R S D R C _ L P R ]
str r3 , . s a v e d _ s a m 9 _ l p r1
bic r3 , r3 , #A T 91 _ D D R S D R C _ L P C B
orr r3 , r3 , #A T 91 _ D D R S D R C _ L P C B _ S E L F _ R E F R E S H
str r3 , [ r2 , #A T 91 _ D D R S D R C _ L P R ]
no_2nd_ddrc :
b e x i t _ s r a m c _ s f
ddrc_exit_sf :
2015-02-05 14:02:09 +08:00
/* Restore MDR in case of LPDDR1 */
2015-03-09 11:48:26 +08:00
ldr r3 , . s a v e d _ s a m 9 _ m d r
str r3 , [ r2 , #A T 91 _ D D R S D R C _ M D R ]
2010-06-21 14:59:27 +01:00
/* Restore LPR on AT91 with DDRAM */
2015-03-09 11:48:26 +08:00
ldr r3 , . s a v e d _ s a m 9 _ l p r
str r3 , [ r2 , #A T 91 _ D D R S D R C _ L P R ]
2010-06-21 14:59:27 +01:00
2015-03-09 11:48:26 +08:00
/* If using the 2nd ddr controller */
ldr r2 , . s r a m c1 _ b a s e
cmp r2 , #0
ldrne r3 , . s a v e d _ s a m 9 _ m d r1
strne r3 , [ r2 , #A T 91 _ D D R S D R C _ M D R ]
ldrne r3 , . s a v e d _ s a m 9 _ l p r1
strne r3 , [ r2 , #A T 91 _ D D R S D R C _ L P R ]
2010-06-21 14:59:27 +01:00
2015-03-09 11:48:26 +08:00
b e x i t _ s r a m c _ s f
2012-02-22 17:50:55 +01:00
/ *
* SDRAMC M e m o r y c o n t r o l l e r
* /
2015-03-09 11:48:26 +08:00
sdramc_sf :
tst r0 , #S R A M C _ S E L F _ F R E S H _ A C T I V E
beq s d r a m c _ e x i t _ s f
/* Active SDRAMC self-refresh mode */
ldr r3 , [ r2 , #A T 91 _ S D R A M C _ L P R ]
str r3 , . s a v e d _ s a m 9 _ l p r
bic r3 , r3 , #A T 91 _ S D R A M C _ L P C B
orr r3 , r3 , #A T 91 _ S D R A M C _ L P C B _ S E L F _ R E F R E S H
str r3 , [ r2 , #A T 91 _ S D R A M C _ L P R ]
sdramc_exit_sf :
ldr r3 , . s a v e d _ s a m 9 _ l p r
str r3 , [ r2 , #A T 91 _ S D R A M C _ L P R ]
exit_sramc_sf :
mov p c , l r
ENDPROC( a t 9 1 _ s r a m c _ s e l f _ r e f r e s h )
.pmc_base :
.word 0
.sramc_base :
.word 0
.sramc1_base :
.word 0
2016-09-27 12:29:50 +02:00
.shdwc :
.word 0
2020-01-20 14:10:05 +02:00
.sfrbu :
2016-09-27 12:29:50 +02:00
.word 0
2015-03-09 11:48:26 +08:00
.memtype :
.word 0
2015-03-09 11:49:46 +08:00
.pm_mode :
.word 0
2020-01-20 14:10:01 +02:00
.mckr_offset :
.word 0
2020-01-20 14:10:04 +02:00
.pmc_version :
.word 0
2008-09-21 21:35:18 +01:00
.saved_mckr :
.word 0
2020-01-20 14:10:02 +02:00
.saved_pllar :
.word 0
2008-09-21 21:35:18 +01:00
.saved_sam9_lpr :
.word 0
2010-06-21 14:59:27 +01:00
.saved_sam9_lpr1 :
.word 0
2015-02-05 14:02:09 +08:00
.saved_sam9_mdr :
.word 0
.saved_sam9_mdr1 :
.word 0
2019-02-14 15:54:57 +00:00
.saved_osc_status :
.word 0
2015-02-05 14:02:09 +08:00
2015-03-09 11:51:09 +08:00
ENTRY( a t 9 1 _ p m _ s u s p e n d _ i n _ s r a m _ s z )
.word . - at9 1 _ p m _ s u s p e n d _ i n _ s r a m