2008-07-03 13:24:38 +04:00
/ *
* linux/ a r c h / a r m / m a c h - o m a p2 / s r a m 2 4 3 x . S
*
* Omap2 s p e c i f i c f u n c t i o n s t h a t n e e d t o b e r u n i n i n t e r n a l S R A M
*
* ( C) C o p y r i g h t 2 0 0 4
* Texas I n s t r u m e n t s , < w w w . t i . c o m >
* Richard W o o d r u f f < r - w o o d r u f f2 @ti.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 i t 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
* published b y t h e 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 L i c e n s e , o r ( a t 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 ,
* but W I T H O U T A N Y W A R R A N T Y ; without even the implied warranty of
* MERCHANTABILITY o r 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 . S e e t h e
* GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e 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
* along w i t h t h i s p r o g r a m ; if not, write to the Free Software
* Foundation, I n c . , 5 9 T e m p l e P l a c e , S u i t e 3 3 0 , B o s t o n ,
* MA 0 2 1 1 1 - 1 3 0 7 U S A
2010-12-22 07:08:14 +03:00
*
* Richard W o o d r u f f n o t e s t h a t a n y c h a n g e s t o t h i s c o d e m u s t b e c a r e f u l l y
* audited a n d t e s t e d t o e n s u r e t h a t t h e y d o n ' t c a u s e a T L B m i s s w h i l e
* the S D R A M i s i n a c c e s s i b l e . S u c h a s i t u a t i o n w i l l c r a s h t h e s y s t e m
* since i t w i l l c a u s e t h e A R M M M U t o a t t e m p t t o w a l k t h e p a g e t a b l e s .
* These c r a s h e s m a y b e i n t e r m i t t e n t .
2008-07-03 13:24:38 +04:00
* /
# include < l i n u x / l i n k a g e . h >
2012-02-24 22:34:35 +04:00
2008-07-03 13:24:38 +04:00
# include < a s m / a s s e m b l e r . h >
2012-02-24 22:34:35 +04:00
2012-08-31 21:59:07 +04:00
# include " s o c . h "
2012-02-24 22:34:35 +04:00
# include " i o m a p . h "
2012-10-21 11:01:10 +04:00
# include " p r m 2 x x x . h "
2012-10-21 11:01:11 +04:00
# include " c m 2 x x x . h "
2008-07-03 13:24:38 +04:00
# include " s d r c . h "
.text
2011-02-02 18:38:06 +03:00
.align 3
2008-07-03 13:24:38 +04:00
ENTRY( o m a p24 3 x _ s r a m _ d d r _ i n i t )
stmfd s p ! , { r0 - r12 , l r } @ save registers on stack
mov r12 , r2 @ capture CS1 vs CS0
mov r8 , r3 @ capture force parameter
/* frequency shift down */
ldr r2 , o m a p24 3 x _ s d i _ c m _ c l k s e l 2 _ p l l @ get address of dpllout reg
mov r3 , #0x1 @ value for 1x operation
str r3 , [ r2 ] @ go to L1-freq operation
/* voltage shift down */
mov r9 , #0x1 @ set up for L1 voltage call
bl v o l t a g e _ s h i f t @ go drop voltage
/* dll lock mode */
ldr r11 , o m a p24 3 x _ s d i _ s d r c _ d l l a _ c t r l @ addr of dlla ctrl
ldr r10 , [ r11 ] @ get current val
cmp r12 , #0x1 @ cs1 base (2422 es2.05/1)
addeq r11 , r11 , #0x8 @ if cs1 base, move to DLLB
mvn r9 , #0x4 @ mask to get clear bit2
and r10 , r10 , r9 @ clear bit2 for lock mode.
orr r10 , r10 , #0x8 @ make sure DLL on (es2 bit pos)
2015-05-14 18:18:46 +03:00
orr r10 , r10 , #0x2 @ 90 degree phase for all below 133MHz
2008-07-03 13:24:38 +04:00
str r10 , [ r11 ] @ commit to DLLA_CTRL
bl i _ d l l _ w a i t @ wait for dll to lock
/* get dll value */
add r11 , r11 , #0x4 @ get addr of status reg
ldr r10 , [ r11 ] @ get locked value
/* voltage shift up */
mov r9 , #0x0 @ shift back to L0-voltage
bl v o l t a g e _ s h i f t @ go raise voltage
/* frequency shift up */
mov r3 , #0x2 @ value for 2x operation
str r3 , [ r2 ] @ go to L0-freq operation
/* reset entry mode for dllctrl */
sub r11 , r11 , #0x4 @ move from status to ctrl
cmp r12 , #0x1 @ normalize if cs1 based
subeq r11 , r11 , #0x8 @ possibly back to DLLA
cmp r8 , #0x1 @ if forced unlock exit
orreq r1 , r1 , #0x4 @ make sure exit with unlocked value
str r1 , [ r11 ] @ restore DLLA_CTRL high value
add r11 , r11 , #0x8 @ move to DLLB_CTRL addr
str r1 , [ r11 ] @ set value DLLB_CTRL
bl i _ d l l _ w a i t @ wait for possible lock
/* set up for return, DDR should be good */
str r10 , [ r0 ] @ write dll_status and return counter
ldmfd s p ! , { r0 - r12 , p c } @ restore regs and return
/* ensure the DLL has relocked */
i_dll_wait :
mov r4 , #0x800 @ delay DLL relock, min 0x400 L3 clocks
i_dll_delay :
subs r4 , r4 , #0x1
bne i _ d l l _ d e l a y
2014-06-30 19:29:12 +04:00
ret l r
2008-07-03 13:24:38 +04:00
/ *
* shift u p o r d o w n v o l t a g e , u s e R 9 a s i n p u t t o t e l l l e v e l .
* wait f o r i t t o f i n i s h , u s e 3 2 k s y n c c o u n t e r , 1 t i c k =31uS .
* /
voltage_shift :
ldr r4 , o m a p24 3 x _ s d i _ p r c m _ v o l t c t r l @ get addr of volt ctrl.
ldr r5 , [ r4 ] @ get value.
ldr r6 , p r c m _ m a s k _ v a l @ get value of mask
and r5 , r5 , r6 @ apply mask to clear bits
orr r5 , r5 , r9 @ bulld value for L0/L1-volt operation.
str r5 , [ r4 ] @ set up for change.
mov r3 , #0x4000 @ get val for force
orr r5 , r5 , r3 @ build value for force
str r5 , [ r4 ] @ Force transition to L1
ldr r3 , o m a p24 3 x _ s d i _ t i m e r _ 3 2 k s y n c t _ c r @ get addr of counter
ldr r5 , [ r3 ] @ get value
add r5 , r5 , #0x3 @ give it at most 93uS
volt_delay :
ldr r7 , [ r3 ] @ get timer value
cmp r5 , r7 @ time up?
bhi v o l t _ d e l a y @ not yet->branch
2014-06-30 19:29:12 +04:00
ret l r @ back to caller.
2008-07-03 13:24:38 +04:00
omap243x_sdi_cm_clksel2_pll :
.word OMAP2 4 3 0 _ C M _ R E G A D D R ( P L L _ M O D , C M _ C L K S E L 2 )
omap243x_sdi_sdrc_dlla_ctrl :
.word OMAP2 4 3 X _ S D R C _ R E G A D D R ( S D R C _ D L L A _ C T R L )
omap243x_sdi_prcm_voltctrl :
2009-05-25 22:26:42 +04:00
.word OMAP2430_PRCM_VOLTCTRL
2008-07-03 13:24:38 +04:00
prcm_mask_val :
.word 0xFFFF3FFC
omap243x_sdi_timer_32ksynct_cr :
2009-10-20 02:25:31 +04:00
.word OMAP2 _ L 4 _ I O _ A D D R E S S ( O M A P 2 4 3 0 _ 3 2 K S Y N C T _ B A S E + 0 x01 0 )
2008-07-03 13:24:38 +04:00
ENTRY( o m a p24 3 x _ s r a m _ d d r _ i n i t _ s z )
.word . - omap2 4 3 x _ s r a m _ d d r _ i n i t
/ *
* Reprograms m e m o r y t i m i n g s .
* r0 = [ P R C M _ F U L L | P R C M _ H A L F ] r1 = S D R C _ D L L A _ C T R L v a l u e r2 = [ D D R | S D R ]
* PRCM_ F U L L = 2 , P R C M _ H A L F = 1 , D D R = 1 , S D R = 0
* /
2011-02-02 18:38:06 +03:00
.align 3
2008-07-03 13:24:38 +04:00
ENTRY( o m a p24 3 x _ s r a m _ r e p r o g r a m _ s d r c )
stmfd s p ! , { r0 - r10 , l r } @ save registers on stack
mov r3 , #0x0 @ clear for mrc call
mcr p15 , 0 , r3 , c7 , c10 , 4 @ memory barrier, finish ARM SDR/DDR
nop
nop
ldr r6 , o m a p24 3 x _ s r s _ s d r c _ r f r _ c t r l @ get addr of refresh reg
ldr r5 , [ r6 ] @ get value
mov r5 , r5 , l s r #8 @ isolate rfr field and drop burst
cmp r0 , #0x1 @ going to half speed?
movne r9 , #0x0 @ if up set flag up for pre up, hi volt
blne v o l t a g e _ s h i f t _ c @ adjust voltage
cmp r0 , #0x1 @ going to half speed (post branch link)
moveq r5 , r5 , l s r #1 @ divide by 2 if to half
movne r5 , r5 , l s l #1 @ mult by 2 if to full
mov r5 , r5 , l s l #8 @ put rfr field back into place
add r5 , r5 , #0x1 @ turn on burst of 1
ldr r4 , o m a p24 3 x _ s r s _ c m _ c l k s e l 2 _ p l l @ get address of out reg
ldr r3 , [ r4 ] @ get curr value
orr r3 , r3 , #0x3
bic r3 , r3 , #0x3 @ clear lower bits
orr r3 , r3 , r0 @ new state value
str r3 , [ r4 ] @ set new state (pll/x, x=1 or 2)
nop
nop
moveq r9 , #0x1 @ if speed down, post down, drop volt
bleq v o l t a g e _ s h i f t _ c
mcr p15 , 0 , r3 , c7 , c10 , 4 @ memory barrier
str r5 , [ r6 ] @ set new RFR_1 value
add r6 , r6 , #0x30 @ get RFR_2 addr
str r5 , [ r6 ] @ set RFR_2
nop
cmp r2 , #0x1 @ (SDR or DDR) do we need to adjust DLL
bne f r e q _ o u t @ leave if SDR, no DLL function
/* With DDR, we need to take care of the DLL for the frequency change */
ldr r2 , o m a p24 3 x _ s r s _ s d r c _ d l l a _ c t r l @ addr of dlla ctrl
str r1 , [ r2 ] @ write out new SDRC_DLLA_CTRL
add r2 , r2 , #0x8 @ addr to SDRC_DLLB_CTRL
str r1 , [ r2 ] @ commit to SDRC_DLLB_CTRL
mov r1 , #0x2000 @ wait DLL relock, min 0x400 L3 clocks
dll_wait :
subs r1 , r1 , #0x1
bne d l l _ w a i t
freq_out :
ldmfd s p ! , { r0 - r10 , p c } @ restore regs and return
/ *
* shift u p o r d o w n v o l t a g e , u s e R 9 a s i n p u t t o t e l l l e v e l .
* wait f o r i t t o f i n i s h , u s e 3 2 k s y n c c o u n t e r , 1 t i c k =31uS .
* /
voltage_shift_c :
ldr r10 , o m a p24 3 x _ s r s _ p r c m _ v o l t c t r l @ get addr of volt ctrl
ldr r8 , [ r10 ] @ get value
ldr r7 , d d r _ p r c m _ m a s k _ v a l @ get value of mask
and r8 , r8 , r7 @ apply mask to clear bits
orr r8 , r8 , r9 @ bulld value for L0/L1-volt operation.
str r8 , [ r10 ] @ set up for change.
mov r7 , #0x4000 @ get val for force
orr r8 , r8 , r7 @ build value for force
str r8 , [ r10 ] @ Force transition to L1
ldr r10 , o m a p24 3 x _ s r s _ t i m e r _ 3 2 k s y n c t @ get addr of counter
ldr r8 , [ r10 ] @ get value
add r8 , r8 , #0x2 @ give it at most 62uS (min 31+)
volt_delay_c :
ldr r7 , [ r10 ] @ get timer value
cmp r8 , r7 @ time up?
bhi v o l t _ d e l a y _ c @ not yet->branch
2014-06-30 19:29:12 +04:00
ret l r @ back to caller
2008-07-03 13:24:38 +04:00
omap243x_srs_cm_clksel2_pll :
.word OMAP2 4 3 0 _ C M _ R E G A D D R ( P L L _ M O D , C M _ C L K S E L 2 )
omap243x_srs_sdrc_dlla_ctrl :
.word OMAP2 4 3 X _ S D R C _ R E G A D D R ( S D R C _ D L L A _ C T R L )
omap243x_srs_sdrc_rfr_ctrl :
.word OMAP2 4 3 X _ S D R C _ R E G A D D R ( S D R C _ R F R _ C T R L _ 0 )
omap243x_srs_prcm_voltctrl :
2009-05-25 22:26:42 +04:00
.word OMAP2430_PRCM_VOLTCTRL
2008-07-03 13:24:38 +04:00
ddr_prcm_mask_val :
.word 0xFFFF3FFC
omap243x_srs_timer_32ksynct :
2009-10-20 02:25:31 +04:00
.word OMAP2 _ L 4 _ I O _ A D D R E S S ( O M A P 2 4 3 0 _ 3 2 K S Y N C T _ B A S E + 0 x01 0 )
2008-07-03 13:24:38 +04:00
ENTRY( o m a p24 3 x _ s r a m _ r e p r o g r a m _ s d r c _ s z )
.word . - omap2 4 3 x _ s r a m _ r e p r o g r a m _ s d r c
/ *
* Set d i v i d e r s a n d p l l . A l s o r e c a l c u l a t e D L L v a l u e f o r D D R a n d u n l o c k m o d e .
* /
2011-02-02 18:38:06 +03:00
.align 3
2008-07-03 13:24:38 +04:00
ENTRY( o m a p24 3 x _ s r a m _ s e t _ p r c m )
stmfd s p ! , { r0 - r12 , l r } @ regs to stack
adr r4 , p b e g i n @ addr of preload start
adr r8 , p e n d @ addr of preload end
mcrr p15 , 1 , r8 , r4 , c12 @ preload into icache
pbegin :
/* move into fast relock bypass */
ldr r8 , o m a p24 3 x _ s s p _ p l l _ c t l @ get addr
ldr r5 , [ r8 ] @ get val
mvn r6 , #0x3 @ clear mask
and r5 , r5 , r6 @ clear field
orr r7 , r5 , #0x2 @ fast relock val
str r7 , [ r8 ] @ go to fast relock
ldr r4 , o m a p24 3 x _ s s p _ p l l _ s t a t @ addr of stat
block :
/* wait for bypass */
ldr r8 , [ r4 ] @ stat value
and r8 , r8 , #0x3 @ mask for stat
cmp r8 , #0x1 @ there yet
bne b l o c k @ loop if not
/* set new dpll dividers _after_ in bypass */
ldr r4 , o m a p24 3 x _ s s p _ p l l _ d i v @ get addr
str r0 , [ r4 ] @ set dpll ctrl val
ldr r4 , o m a p24 3 x _ s s p _ s e t _ c o n f i g @ get addr
mov r8 , #1 @ valid cfg msk
str r8 , [ r4 ] @ make dividers take
mov r4 , #100 @ dead spin a bit
wait_a_bit :
subs r4 , r4 , #1 @ dec loop
bne w a i t _ a _ b i t @ delay done?
/* check if staying in bypass */
cmp r2 , #0x1 @ stay in bypass?
beq p e n d @ jump over dpll relock
/* relock DPLL with new vals */
ldr r5 , o m a p24 3 x _ s s p _ p l l _ s t a t @ get addr
ldr r4 , o m a p24 3 x _ s s p _ p l l _ c t l @ get addr
orr r8 , r7 , #0x3 @ val for lock dpll
str r8 , [ r4 ] @ set val
mov r0 , #1000 @ dead spin a bit
wait_more :
subs r0 , r0 , #1 @ dec loop
bne w a i t _ m o r e @ delay done?
wait_lock :
ldr r8 , [ r5 ] @ get lock val
and r8 , r8 , #3 @ isolate field
cmp r8 , #2 @ locked?
bne w a i t _ l o c k @ wait if not
pend :
/* update memory timings & briefly lock dll */
ldr r4 , o m a p24 3 x _ s s p _ s d r c _ r f r @ get addr
str r1 , [ r4 ] @ update refresh timing
ldr r11 , o m a p24 3 x _ s s p _ d l l a _ c t r l @ get addr of DLLA ctrl
ldr r10 , [ r11 ] @ get current val
mvn r9 , #0x4 @ mask to get clear bit2
and r10 , r10 , r9 @ clear bit2 for lock mode
orr r10 , r10 , #0x8 @ make sure DLL on (es2 bit pos)
str r10 , [ r11 ] @ commit to DLLA_CTRL
add r11 , r11 , #0x8 @ move to dllb
str r10 , [ r11 ] @ hit DLLB also
mov r4 , #0x800 @ relock time (min 0x400 L3 clocks)
wait_dll_lock :
subs r4 , r4 , #0x1
bne w a i t _ d l l _ l o c k
nop
ldmfd s p ! , { r0 - r12 , p c } @ restore regs and return
omap243x_ssp_set_config :
2009-05-25 22:26:42 +04:00
.word OMAP2430_PRCM_CLKCFG_CTRL
2008-07-03 13:24:38 +04:00
omap243x_ssp_pll_ctl :
.word OMAP2 4 3 0 _ C M _ R E G A D D R ( P L L _ M O D , C M _ C L K E N )
omap243x_ssp_pll_stat :
.word OMAP2 4 3 0 _ C M _ R E G A D D R ( P L L _ M O D , C M _ I D L E S T )
omap243x_ssp_pll_div :
.word OMAP2 4 3 0 _ C M _ R E G A D D R ( P L L _ M O D , C M _ C L K S E L 1 )
omap243x_ssp_sdrc_rfr :
.word OMAP2 4 3 X _ S D R C _ R E G A D D R ( S D R C _ R F R _ C T R L _ 0 )
omap243x_ssp_dlla_ctrl :
.word OMAP2 4 3 X _ S D R C _ R E G A D D R ( S D R C _ D L L A _ C T R L )
ENTRY( o m a p24 3 x _ s r a m _ s e t _ p r c m _ s z )
.word . - omap2 4 3 x _ s r a m _ s e t _ p r c m