SDRAM初始化
DDR配置过程比较复杂,基本上是按照DDR控制器的时序要求来做的,其中很多参数要结合DDR芯片本身的参数来定,还有些参数是时序参数,要去详细计算。所以DDR配置非常繁琐、细致、专业。所以我们对DDR初始化的态度就是:学会这种思路和方法,结合文档和代码能看懂,会算一些常见的参数即可。
.global sdram_asm_init sdram_asm_init: ldr r0, =0xf1e00000 ldr r1, =0x0 str r1, [r0, #0x0] /* DMC0 Drive Strength (Setting 2X) */ ldr r0, =ELFIN_GPIO_BASE ldr r1, =0x0000AAAA str r1, [r0, #MP1_0DRV_SR_OFFSET] // 寄存器中对应0b10,就是2X ldr r1, =0x0000AAAA str r1, [r0, #MP1_1DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP1_2DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP1_3DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP1_4DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP1_5DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP1_6DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP1_7DRV_SR_OFFSET] ldr r1, =0x00002AAA str r1, [r0, #MP1_8DRV_SR_OFFSET] /* DMC1 Drive Strength (Setting 2X) */ ldr r0, =ELFIN_GPIO_BASE ldr r1, =0x0000AAAA str r1, [r0, #MP2_0DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP2_1DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP2_2DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP2_3DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP2_4DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP2_5DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP2_6DRV_SR_OFFSET] ldr r1, =0x0000AAAA str r1, [r0, #MP2_7DRV_SR_OFFSET] ldr r1, =0x00002AAA str r1, [r0, #MP2_8DRV_SR_OFFSET] /* DMC0 initialization at single Type*/ ldr r0, =APB_DMC_0_BASE ldr r1, =0x00101000 @PhyControl0 DLL parameter setting, manual 0x00101000 str r1, [r0, #DMC_PHYCONTROL0] ldr r1, =0x00000086 @PhyControl1 DLL parameter setting, LPDDR/LPDDR2 Case str r1, [r0, #DMC_PHYCONTROL1] ldr r1, =0x00101002 @PhyControl0 DLL on str r1, [r0, #DMC_PHYCONTROL0] ldr r1, =0x00101003 @PhyControl0 DLL start str r1, [r0, #DMC_PHYCONTROL0] find_lock_val: ldr r1, [r0, #DMC_PHYSTATUS] @Load Phystatus register value and r2, r1, #0x7 cmp r2, #0x7 @Loop until DLL is locked bne find_lock_val and r1, #0x3fc0 mov r2, r1, LSL #18 orr r2, r2, #0x100000 orr r2 ,r2, #0x1000 orr r1, r2, #0x3 @Force Value locking str r1, [r0, #DMC_PHYCONTROL0] #if 0 /* Memory margin test 10.01.05 */ orr r1, r2, #0x1 @DLL off str r1, [r0, #DMC_PHYCONTROL0] #endif /* setting DDR2 */ ldr r1, =0x0FFF2010 @ConControl auto refresh off str r1, [r0, #DMC_CONCONTROL] ldr r1, =DMC0_MEMCONTROL @MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off str r1, [r0, #DMC_MEMCONTROL] ldr r1, =DMC0_MEMCONFIG_0 @MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed str r1, [r0, #DMC_MEMCONFIG0] ldr r1, =DMC0_MEMCONFIG_1 @MemConfig1 str r1, [r0, #DMC_MEMCONFIG1] ldr r1, =0xFF000000 @PrechConfig str r1, [r0, #DMC_PRECHCONFIG] ldr r1, =DMC0_TIMINGA_REF @TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E) str r1, [r0, #DMC_TIMINGAREF] ldr r1, =DMC0_TIMING_ROW @TimingRow for @200MHz str r1, [r0, #DMC_TIMINGROW] ldr r1, =DMC0_TIMING_DATA @TimingData CL=3 str r1, [r0, #DMC_TIMINGDATA] ldr r1, =DMC0_TIMING_PWR @TimingPower str r1, [r0, #DMC_TIMINGPOWER] ldr r1, =0x07000000 @DirectCmd chip0 Deselect str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x01000000 @DirectCmd chip0 PALL str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00020000 @DirectCmd chip0 EMRS2 str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00030000 @DirectCmd chip0 EMRS3 str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable) str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4 str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x01000000 @DirectCmd chip0 PALL str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x05000000 @DirectCmd chip0 REFA str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x05000000 @DirectCmd chip0 REFA str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset) str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00010780 @DirectCmd chip0 EMRS1 (OCD default) str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (OCD exit) str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x07100000 @DirectCmd chip1 Deselect str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x01100000 @DirectCmd chip1 PALL str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00120000 @DirectCmd chip1 EMRS2 str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00130000 @DirectCmd chip1 EMRS3 str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (MEM DLL on, DQS# disable) str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00100542 @DirectCmd chip1 MRS (MEM DLL reset) CL=4, BL=4 str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x01100000 @DirectCmd chip1 PALL str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x05100000 @DirectCmd chip1 REFA str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x05100000 @DirectCmd chip1 REFA str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00100442 @DirectCmd chip1 MRS (MEM DLL unreset) str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00110780 @DirectCmd chip1 EMRS1 (OCD default) str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (OCD exit) str r1, [r0, #DMC_DIRECTCMD] ldr r1, =0x0FF02030 @ConControl auto refresh on str r1, [r0, #DMC_CONCONTROL] ldr r1, =0xFFFF00FF @PwrdnConfig str r1, [r0, #DMC_PWRDNCONFIG] ldr r1, =0x00202400 @MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off str r1, [r0, #DMC_MEMCONTROL] // 上面是DRAM0初始化步骤