blob: a1c0c7149ef45306bdb5401f60dccff669156cbd [file] [log] [blame]
/*
* Low-level frequency change code
*
* Copyright (C) 2009, Marvell Semicondutor.
*
* This software program is licensed subject to the GNU General Public License
* (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
*/
#include <config.h>
.global freq_init_sram, freq_chg_seq
@******************************************************************************
@
@ freq_init_sram
@
@ Copy frequency change code into ISRAM
@
@ Inputs:
@ r0 = Start address of relocated program
@
@ Outputs:
@ None
@
freq_init_sram:
stmfd sp!, {r0 - r12, lr}
ldr r3, =freq_sram_start
ldr r4, =freq_sram_end
add r4, r4, #0x200
rel_ram:
ldmia r3!, {r5 - r12}
stmia r0!, {r5 - r12}
cmp r3, r4
ble rel_ram
ldmfd sp!, {r0 - r12, pc}
@******************************************************************************
@
@ freq_chg_seq
@
@ frequency change sequence
@
@ Inputs:
@ r0 = Start address of relocated program
@ r1 = Start address of relocated stack
@ r2 = operating points
@ r3 = chip steppings: 0 - z0, 1 - z1, 2 - a0 and 3 - a1
@
@ Outputs:
@ None
@
#define PMUM_FCCR_OFF 0x0008
#define PMUA_CC_AP_OFF 0x0004
freq_chg_seq:
@ save registers on stack
stmfd sp!, {r3 - r12, lr}
mov r12, r0 @ save start address of program in r12
mov r11, r1 @ save start address of stack in r11
mov r10, sp @ save sp in r10
mov sp, r11 @ set up new stack address
stmfd sp!, {lr} @ store the return address
#if (defined(CONFIG_MMP2_JASPER) || defined(CONFIG_MMP2_FLINT) || defined(CONFIG_MACH_BROWNSTONE) || defined(CONFIG_MMP2_G50))
ldr r4, =0xd0000000 @ DMEM base address
#else
ldr r4, =0xb0000000 @ DMEM base address
#endif
ldr r5, =0xd4050000 @ PMUM base address
ldr r6, =0xd4282800 @ PMUA base address
mov pc, r0
freq_sram_start:
cmp r3, #0x3
bne 1f
ldr r7, =0x1
str r7, [r4, #0x7e0]
ldr r7, =0x40
str r7, [r4, #0x120]
b 1f
.align 5
1:
#if (defined(CONFIG_MMP2_JASPER) || defined(CONFIG_MMP2_FLINT) || defined(CONFIG_MACH_BROWNSTONE) || defined(CONFIG_MMP2_G50))
@
@ frequency change
@
@ turn on all clocks and allow freq in debug register
ldr r7, =0xffffffff
str r7, [r5, #0x0024]
@ ldr r7, =0x00061808
@ str r7, [r6, #0x88]
@ change to PLL1/2 first, start-up operation point
ldr r7, =0x00000000
str r7, [r5, #0x8]
ldr r7, =0x08fd96d9
str r7, [r6, #0x00]
ldr r7, =0x78fd96d9
str r7, [r6, #0x04]
@ pclk 100/dclk 400/aclk 100
cmp r2, #0x0
bne 2f
@ select PLL2 frequency, 988MHz
ldr r7, =0x08600622
str r7, [r5, #0x0414]
ldr r7, =0x00FFFE00
str r7, [r5, #0x0034]
ldr r7, =0x00238A00
str r7, [r5, #0x0034]
ldr r7, =0x00238B00
str r7, [r5, #0x0034]
ldr r7, =0x28600622
str r7, [r5, #0x0414]
@ select clock source, PJ4-PLL1/2, SP-PLL1/2, AXI/DDR-PLL1
ldr r7, =0x00800000
str r7, [r5, #0x0008]
@ divider setting and frequency change request, core-100, ddr-400, axi-100
ldr r7, =0x08fd8041
str r7, [r6, #0x00]
ldr r7, =0xf8ff86db
str r7, [r6, #0x04]
@ pclk 200/dclk 400/aclk 200
2:
cmp r2, #0x1
bne 3f
@ select PLL2 frequency, 988MHz
ldr r7, =0x08600622
str r7, [r5, #0x0414]
ldr r7, =0x00FFFE00
str r7, [r5, #0x0034]
ldr r7, =0x00238A00
str r7, [r5, #0x0034]
ldr r7, =0x00238B00
str r7, [r5, #0x0034]
ldr r7, =0x28600622
str r7, [r5, #0x0414]
@ select clock source, PJ4-PLL1/2, SP-PLL1/2, AXI/DDR-PLL1
ldr r7, =0x00800000
str r7, [r5, #0x0008]
@ divider setting and frequency change request, core-200, ddr-400, axi-200
ldr r7, =0x08fd8041
str r7, [r6, #0x00]
ldr r7, =0xf8fd8249
str r7, [r6, #0x04]
@ pclk 400/dclk 400/aclk 200
3:
cmp r2, #0x2
bne 4f
@ select PLL2 frequency, 988MHz
ldr r7, =0x08600622
str r7, [r5, #0x0414]
ldr r7, =0x00FFFE00
str r7, [r5, #0x0034]
ldr r7, =0x00238A00
str r7, [r5, #0x0034]
ldr r7, =0x00238B00
str r7, [r5, #0x0034]
ldr r7, =0x28600622
str r7, [r5, #0x0414]
@ select clock source, PJ4-PLL1/2, SP-PLL1/2, AXI/DDR-PLL1
ldr r7, =0x00800000
str r7, [r5, #0x0008]
@ divider setting and frequency change request, core-400, ddr-400, axi-200
ldr r7, =0x08fd8041
str r7, [r6, #0x00]
ldr r7, =0xf8fd8000
str r7, [r6, #0x04]
@ pclk 800/dclk 400/aclk 266
4:
cmp r2, #0x3
bne 5f
@ select PLL2 frequency, 988MHz
ldr r7, =0x08600322
str r7, [r5, #0x0414]
ldr r7, =0x00FFFE00
str r7, [r5, #0x0034]
ldr r7, =0x00238a00
str r7, [r5, #0x0034]
ldr r7, =0x00238b00
str r7, [r5, #0x0034]
ldr r7, =0x28600622
str r7, [r5, #0x0414]
@ select clock source, PJ4-PLL1, SP-PLL1/2, AXI/DDR-PLL1
ldr r7, =0x20800000
str r7, [r5, #0x0008]
@ divider setting and frequency change request, core-800, ddr-400, axi-200
ldr r7, =0x08fd0248
str r7, [r6, #0x00]
ldr r7, =0xf8fd0248
str r7, [r6, #0x04]
@ pclk 988/dclk 400/aclk 266
5:
cmp r2, #0x4
bne 6f
@ select PLL2 frequency, 988MHz
ldr r7, =0x08600622
str r7, [r5, #0x0414]
ldr r7, =0x00FFFE00
str r7, [r5, #0x0034]
ldr r7, =0x00238A00
str r7, [r5, #0x0034]
ldr r7, =0x00238B00
str r7, [r5, #0x0034]
ldr r7, =0x28600622
str r7, [r5, #0x0414]
@ select clock source, PJ4-PLL2, SP-PLL1/2, AXI/DDR-PLL1
ldr r7, =0x40800000
str r7, [r5, #0x0008]
@ divider setting and frequency change request, core-988, ddr-400, axi-266
ldr r7, =0x08fd0248
str r7, [r6, #0x00]
ldr r7, =0xf8fd0248
str r7, [r6, #0x04]
b 6f
@dummy reads
mov r8, #500
mov r9, #0x0
loop_delay:
ldr r7, [r9, #0x0]
subs r8, r8, #1
bne loop_delay
6:
@
@ ddr re-calibration after frequency change
@
ldr r7, =freq_sram_start
#if (defined(CONFIG_DDR_MICRON_256M))
ldr r8, =mmp2_micron256_ddr
#elif (defined(CONFIG_DDR_EPD_512M))
ldr r8, =mmp2_epd512_ddr
#elif (defined(CONFIG_MMP2_FLINT))
ldr r8, =mmp2_epd256_ddr
#elif (defined(CONFIG_DDR3_EPD_1G))
cmp r3, #0x3
beq a1_setting
ldr r8, =mmp2_epd1024_ddr3
b ddr_recalibrate
a1_setting:
ldr r8, =a1_mmp2_epd1024_ddr3
#elif (defined(CONFIG_DDR3_EPD_512M))
ldr r8, =a1_mmp2_epd512_ddr3
#else
#error "please define ddr table"
#endif
ddr_recalibrate:
sub r8, r8, r7
loop:
ldr r3, [r0, r8]
cmp r3, #0x80000000
beq finished
cmp r3, #0x40000000
bne 200f
add r8, r8, #0x8
ldr r7, [r0, r8]
ldr r12, [r4, r7]
add r8, r8, #0x8
b loop
200:
cmp r3, #0x20000000
bne 300f
add r8, r8, #0x8
ldr r7, [r0, r8]
ldr r12, [r4, r7]
add r8, r8, #0x4
ldr r9, [r0, r8]
and r9, r9, r12
str r9, [r4, r7]
add r8, r8, #0x4
b loop
300:
cmp r3, #0x10000000
bne 400f
add r8, r8, #0x8
ldr r7, [r0, r8]
ldr r12, [r4, r7]
add r8, r8, #0x4
ldr r9, [r0, r8]
orr r9, r9, r12
str r9, [r4, r7]
add r8, r8, #0x4
b loop
400:
ldr r7, [r0, r8]
add r8, r8, #0x4
ldr r9, [r0, r8]
str r9, [r4, r7]
add r8, r8, #0x4
b loop
finished:
@ ldr r7, =0x80
@ str r7, [r4, #0x120]
ldr r7, =0x0
str r7, [r4, #0x7e0]
@dummy reads for PHY DQ byte read DLLs to update
mov r8, #131
mov r9, #0x0
1:
ldr r7, [r9, #0x0]
subs r8, r8, #1
bne 1b
ldr r7, [r4, #0x240]
#else
@ frequency change sequence
ldr r7, =0x2000088e
str r7, [r5, #PMUM_FCCR_OFF]
ldr r7, =0xf0e482f8
str r7, [r6, #PMUA_CC_AP_OFF]
@ ddr caliberation
#endif
@ return
ldmfd sp!, {lr}
mov sp, r10 @ restore stack address
ldmfd sp!, {r3 - r12, pc}
/*
* special translation for offset:
* 0x10000000 or
* 0x20000000 and
* 0x40000000 read
* 0x80000000 end
*/
#if (defined(CONFIG_DDR_MICRON_256M))
mmp2_micron256_ddr:
.long 0x010, 0xD0004D56 @ CONFIG_DECODE_ADDR
.long 0x100, 0x000B0001 @ MMAP
.long 0x110, 0x080B0001
.long 0x020, 0x00006320 @ CONFIG_TYPE
.long 0x030, 0x00006320
.long 0xB40, 0x00000000
.long 0xB50, 0x00000000
.long 0x050, 0x4CD800C5 @ TIMING
.long 0x060, 0x84660342
.long 0x190, 0x2000381B
.long 0x1C0, 0x3023009D
.long 0x650, 0x00110142
.long 0x660, 0x02424190
.long 0x080, 0x00005000 @ CTRL
.long 0x090, 0x00080010
.long 0x0F0, 0xC0000000
.long 0x1A0, 0x20C08115
.long 0x280, 0x01010101
.long 0x760, 0x00000000
.long 0x770, 0x03000000
.long 0x780, 0x00000133
.long 0x7B0, 0x01010101
.long 0x7D0, 0x0000000F
.long 0x7E0, 0x00000000
.long 0x540, 0x00000000 @ MCB
.long 0x570, 0x00000001
.long 0x580, 0x00000000
.long 0x590, 0x00000000
.long 0x5A0, 0x00000000
.long 0x5B0, 0x00000000
.long 0x180, 0x00000000 @ WRITE_PROTECTION
.long 0x210, 0x00000000 @ __PHY Deskew PLL config and PHY initialization
.long 0x240, 0x80000000
.long 0x10000000, 0x0 @ DLL reset, Need this after any DCLK freq change
.long 0x240, 0x20000000
.long 0x20000000, 0x0
.long 0x240, 0xdfffffff
.long 0x10000000, 0x0 @ Pad drive strength auto calibration
.long 0x200, 0x00110000
.long 0x40000000, 0x0
.long 0x240, 0x0
.long 0x20000000, 0x0
.long 0x200, 0xfffeffff
.long 0x140, 0x20004455
.long 0x1D0, 0x13300559
.long 0x1E0, 0x03300770
.long 0x1F0, 0x00000077
.long 0x230, 0x20000088
.long 0xE10, 0x00000080
.long 0xE20, 0x00000080
.long 0xE30, 0x00000080
.long 0xE40, 0x00000000
.long 0xE50, 0x00000000
.long 0x120, 0x03000001 @ initialize LPDDR2
.long 0x40000000, 0x0
.long 0x1b0, 0x0
.long 0x410, 0x0302003F
.long 0x120, 0x01001000
.long 0x120, 0x02001000
.long 0x410, 0x03020001
.long 0x410, 0x03020002
.long 0x410, 0x03020003
.long 0x80000000, 0x0
#elif (defined(CONFIG_DDR_EPD_512M))
mmp2_epd512_ddr:
.long 0x010, 0xD0004D56 @ CONFIG_DECODE_ADDR
.long 0x100, 0x000C0001 @ MMAP
.long 0x110, 0x100C0001
.long 0x020, 0x00006420 @ CONFIG_TYPE
.long 0x030, 0x00006420
.long 0xB40, 0x00000000
.long 0xB50, 0x00000000
.long 0x050, 0x4CDA00C5 @ TIMING
.long 0x060, 0x94860342
.long 0x190, 0x2000381B
.long 0x1C0, 0x3023009D
.long 0x650, 0x00110142
.long 0x660, 0x02424190
.long 0x080, 0x00005000 @ CTRL
.long 0x090, 0x00080010
.long 0x0F0, 0xC0000000
.long 0x1A0, 0x20C08115
.long 0x280, 0x01010101
.long 0x760, 0x00000000
.long 0x770, 0x03000000
.long 0x780, 0x00000133
.long 0x7B0, 0x01010101
.long 0x7D0, 0x0000000F
.long 0x7E0, 0x00000000
.long 0x540, 0x00000000 @ MCB
.long 0x570, 0x00000001
.long 0x580, 0x00000000
.long 0x590, 0x00000000
.long 0x5A0, 0x00000000
.long 0x5B0, 0x00000000
.long 0x180, 0x00000000 @ WRITE_PROTECTION
.long 0x210, 0x00000000 @ __PHY Deskew PLL config and PHY initialization
.long 0x240, 0x80000000
.long 0x10000000, 0x0 @ DLL reset, Need this after any DCLK freq change
.long 0x240, 0x20000000
.long 0x20000000, 0x0
.long 0x240, 0xdfffffff
.long 0x10000000, 0x0 @ Pad drive strength auto calibration
.long 0x200, 0x00110000
.long 0x40000000, 0x0
.long 0x240, 0x0
.long 0x20000000, 0x0
.long 0x200, 0xfffeffff
.long 0x140, 0x20004433
.long 0x1D0, 0x13300559
.long 0x1E0, 0x03300990
.long 0x1F0, 0x00000077
.long 0x230, 0x20000088
.long 0xE10, 0x00000080
.long 0xE20, 0x00000080
.long 0xE30, 0x00000080
.long 0xE40, 0x00000000
.long 0xE50, 0x00000000
.long 0x120, 0x03000001 @ initialize LPDDR2
.long 0x40000000, 0x0
.long 0x1b0, 0x0
.long 0x410, 0x0302003F
.long 0x120, 0x01001000
.long 0x120, 0x02001000
.long 0x410, 0x03020001
.long 0x410, 0x03020002
.long 0x410, 0x03020003
.long 0x80000000, 0x0
#elif (defined(CONFIG_MMP2_FLINT))
mmp2_epd256_ddr:
/* offset value */
.long 0x0, 0xD0004D56 @ CONFIG_DECODE_ADDR
.long 0x100, 0x000B0001 @ MMAP
.long 0x110, 0x080B0001
.long 0x20, 0x00006320 @ CONFIG_TYPE
.long 0x30, 0x00006320
.long 0x50, 0x4cd800c5 @ TIMING
.long 0x60, 0x84660342
.long 0x190, 0x2000381B
.long 0x1C0, 0x3023009D
.long 0x650, 0x00110142
.long 0x660, 0x02424190
.long 0xf0, 0xc0000000 @ CTRL
.long 0x1a0, 0x20c08115
.long 0x760, 0x0
.long 0x770, 0x0
.long 0x210, 0x00000000 @ __PHY Deskew PLL config and PHY initialization
.long 0x240, 0x80000000
.long 0x10000000, 0x0 @ DLL reset, Need this after any DCLK freq change
.long 0x240, 0x20000000
.long 0x20000000, 0x0
.long 0x240, 0xdfffffff
.long 0x10000000, 0x0 @ Pad drive strength auto calibration
.long 0x200, 0x00110000
.long 0x40000000, 0x0
.long 0x240, 0x0
.long 0x20000000, 0x0
.long 0x200, 0xfffeffff
.long 0x140, 0x20004433
.long 0x1D0, 0x177C2779
.long 0x1e0, 0x0aa00770
.long 0x1f0, 0xc0000077
.long 0x230, 0x20000108
.long 0xE10, 0x00000100
.long 0xE20, 0x00000100
.long 0xE30, 0x00000100
.long 0xE10, 0x205c7d00
.long 0xE20, 0x205c7d00
.long 0xE30, 0x205c7d00
.long 0x120, 0x03000001 @ initialize LPDDR2
.long 0x40000000, 0x0
.long 0x1b0, 0x0
.long 0x410, 0x0302003f
.long 0x120, 0x01001000
.long 0x120, 0x02001000
.long 0x410, 0x03020001
.long 0x410, 0x03020002
.long 0x410, 0x03020003
.long 0x80000000, 0x0
#elif (defined(CONFIG_DDR3_EPD_1G))
a1_mmp2_epd1024_ddr3:
@ .long 0x010, 0xD0004D56 @ CONFIG_DECODE_ADDR
@ .long 0x100, 0x000D0001 @ MMAP
@ .long 0x110, 0x200D0001
@ .long 0x020, 0x00022430 @ CONFIG_TYPE
@ .long 0x030, 0x00022430
@ .long 0xB40, 0x00000000
@ .long 0xB50, 0x00000000
@ .long 0x050, 0x911500cA @ TIMING
@ .long 0x060, 0x646602C4
@ .long 0x190, 0xc2003053
@ .long 0x1C0, 0x34F4A187
@ .long 0x650, 0x000F0141
@ .long 0x660, 0x04040200
@ .long 0x080, 0x90045000 @ CTRL
@ .long 0x090, 0x00100000
@ .long 0x0F0, 0xC0000000
@ .long 0x1A0, 0x20C0C409
@ .long 0x280, 0x01010101
@ .long 0x760, 0x00000201
@ .long 0x770, 0x0200000A
@ .long 0x780, 0x00000133
@ .long 0x7B0, 0x01010101
@ .long 0x7D0, 0x00000001
@ .long 0x7E0, 0x00000000
@ .long 0x540, 0x00000000 @ MCB
@ .long 0x570, 0x00000001
@ .long 0x580, 0x00000000
@ .long 0x590, 0x00000000
@ .long 0x5A0, 0x00000000
@ .long 0x5B0, 0x00000000
@ .long 0x180, 0x00000000 @ WRITE_PROTECTION
@ .long 0x210, 0x00000000 @ __PHY Deskew PLL config and PHY initialization
.long 0x240, 0x80000000
@ .long 0x10000000, 0x0 @ Pad drive strength auto calibration
@ .long 0x200, 0x00110000
@ .long 0x20000000, 0x0
@ .long 0x200, 0xfffeffff
@ .long 0x140, 0x20004055
@ .long 0x1D0, 0x17721869
@ .long 0x1E0, 0x07700860
@ .long 0x1F0, 0x00000086
.long 0x10000000, 0x0
.long 0x230, 0xf0000000
@ .long 0xE10, 0x00000040
@ .long 0xE20, 0x00000040
@ .long 0xE30, 0x00000040
@ .long 0x10000000, 0x0 @ DLL reset, Need this after any DCLK freq change
.long 0x240, 0x20000000
@ .long 0x10000000, 0x0 @ DLL reset, Need this after any DCLK freq change
.long 0x240, 0x40000000
@ .long 0x20000000, 0x0 @ DLL reset, Need this after any DCLK freq change
@ .long 0x240, 0xdfffffff
.long 0x120, 0x00000080
.long 0x10000000, 0x0
.long 0x80, 0x00000040
.long 0x120, 0x01000100
@ .long 0xE40, 0x00000000
@ .long 0xE50, 0x00000000
@ .long 0x120, 0x03000001 @ initialize LPDDR2
@ .long 0x40000000, 0x0
@ .long 0x1b0, 0x0
@ .long 0x120, 0x01001000
@ .long 0x120, 0x02001000
.long 0x80000000, 0x0
mmp2_epd1024_ddr3:
.long 0x010, 0xD0004D56 @ CONFIG_DECODE_ADDR
.long 0x100, 0x000D0001 @ MMAP
.long 0x110, 0x200D0001
.long 0x020, 0x00222430 @ CONFIG_TYPE
.long 0x030, 0x00222430
.long 0xB40, 0x00000000
.long 0xB50, 0x00000000
.long 0x050, 0x911500cA @ TIMING
.long 0x060, 0x646602C4
.long 0x190, 0xc2003053
.long 0x1C0, 0x34F4A187
.long 0x650, 0x000F0141
.long 0x660, 0x04040200
.long 0x080, 0x00005000 @ CTRL
.long 0x090, 0x00100010
.long 0x0F0, 0xC0000000
.long 0x1A0, 0x20C0C409
.long 0x280, 0x01010101
.long 0x760, 0x00000201
.long 0x770, 0x0100000A
.long 0x780, 0x00000133
.long 0x7B0, 0x01010101
.long 0x7D0, 0x0000000F
.long 0x7E0, 0x00000000
.long 0x540, 0x00000000 @ MCB
.long 0x570, 0x00000001
.long 0x580, 0x00000000
.long 0x590, 0x00000000
.long 0x5A0, 0x00000000
.long 0x5B0, 0x00000000
.long 0x180, 0x00000000 @ WRITE_PROTECTION
.long 0x210, 0x00000000 @ __PHY Deskew PLL config and PHY initialization
.long 0x240, 0x80000000
.long 0x10000000, 0x0 @ Pad drive strength auto calibration
.long 0x200, 0x00110000
.long 0x20000000, 0x0
.long 0x200, 0xfffeffff
.long 0x140, 0x20004055
.long 0x1D0, 0x17721869
.long 0x1E0, 0x07700860
.long 0x1F0, 0x00000086
.long 0x230, 0xd0000040
.long 0xE10, 0x00000040
.long 0xE20, 0x00000040
.long 0xE30, 0x00000040
.long 0x10000000, 0x0 @ DLL reset, Need this after any DCLK freq change
.long 0x240, 0x20000000
.long 0x20000000, 0x0
.long 0x240, 0xdfffffff
.long 0x40000000, 0x0
.long 0x240, 0x0
.long 0xE40, 0x00000000
.long 0xE50, 0x00000000
.long 0x120, 0x03000001 @ initialize LPDDR2
.long 0x40000000, 0x0
.long 0x1b0, 0x0
.long 0x120, 0x01001000
.long 0x120, 0x02001000
.long 0x80000000, 0x0
#elif (defined(CONFIG_DDR3_EPD_512M))
a1_mmp2_epd512_ddr3:
.long 0x240, 0x80000000
.long 0x10000000, 0x0
.long 0x230, 0xf0000000
.long 0x240, 0x20000000
.long 0x240, 0x40000000
.long 0x120, 0x00000080
.long 0x10000000, 0x0
.long 0x80, 0x00000040
.long 0x120, 0x01000100
.long 0x80000000, 0x0
#else
#error "please define ddr table"
#endif
freq_sram_end:
nop