1. 程式人生 > >DDR2初始化程式碼分析[s5pv210, K4T1G164QQ]

DDR2初始化程式碼分析[s5pv210, K4T1G164QQ]

以下流程基本為簡單翻譯(原文參考s5pv210的資料手冊1.2.1.3章節)
1. DMC及DDR2顆粒上電, 且電壓穩定
2. DMC保持CKE為低電平
3. SOC提供時鐘(XDDR2SEL保持高電平以保持CKE為低)
4. 根據實際工作時鐘頻率設定phyControl0.ctrl_start_point和PhyControl0.ctrl_inc
ldr r0, =APB_DMC_0_BASE @ 0xF000_0000
ldr r1, =0x00101000 @ ctrl_start_point: bit[15:8], ctrl_inc: bit[23:16], 按手冊建議,這兩位都設定為0x10
str r1, [r0, #DMC_PHYCONTROL0]

@ 0xF000_0018
5. 設定PhyControl0.ctrl_dll_on為”1”, 以使能PHY DLL
ldr r1, =0x00101002 @ctrl_dll_on: bit[1]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
6. DQS Cleaning: 根據實際工作時鐘頻率和tAC設定PhyControl1.ctrl_shiftc和PhyControl1.ctrl_offsetc (可以和第7步互換順序)
ldr r1, =0x00000086 @ ctrl_shiftc: bit[2:0], 手冊建議設定為6 (DDR2); ctrl_offsetc: bit[14:8], 這裡設定為”0”, ctrl_ref: bit[7:4], 預設值為0x4; 所以, 這裡應該設定為0x00000046系統也能工作, 設定為”86”可能是原始碼作者的錯誤
str r1, [r0, #DMC_PHYCONTROL1]
@ 0xF000_001C
7. 置位PhyControl0.ctrl_start以啟動DLL
ldr r1, =0x00101003 @ ctrl_start: bit[0]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
8. 設定ConControl, 注意此時需要保證auto refresh counter off
ldr r1, =0x0FFF2010 @ default time out cycles: FFF; Read data fetch cycles: 2 (CL後再過2個週期latch資料), disable adaptive QoS, disable DQ swap, disable PHY driving (bi-directional pin拉低以省電, enable是不是更好?), disable read cycle gap for 2 different chips (應該是enable),auto refresh counter off, enable out of order scheduling, revise後的設定為(待測試):0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL]
@ 0xF000_0000
9. 設定MemControl, 所有power down mode要關掉
ldr r1, =0x00202400 @ MemControl BL=4, 2 chip, 位寬x32 (是指通道位寬), DDR2 type, no additional latency for PALL, disable dynamic self refresh, disable timeout precharge, active/precharge power down, dynamic power down off, dynamic clock control: always running, revise後的設定為(待測試):0x00212400
str r1, [r0, #DMC_MEMCONTROL] @ 0xF000_0004
10. 設定MemControl0和MemControl1暫存器(如果有)
ldr r1, =0x20F01323 @ MemConfig0 設定地址範圍0x2000_0000~0x2FFF_FFFF(再在設定的是DMC0,DMC0總共有二片DRAM,每片128MB,因此,嚴謹的設定應該是0x2000_0000~0x27FF_FFFF, MemConfig1的設定是0x4000_0000~0x47FF_FFFF, 在設定DMC1的流程中,MemConfig0的地址範圍可以設定為0x2800_0000~0x2FFF_FFFF, MemConfig1的地址範圍設定為0x4800_0000~0x4FFF_FFFF), Mapping Method[15:12] (1:linterleaved), 10bit Column address, 14bit row address, 8 bank, 這樣算下來容量不對,查手冊得知,應該設定為13bit row address, 8 bank, revised設定:0x20F81313
str r1, [r0, #DMC_MEMCONFIG0] @ 0xF000_0008
ldr r1, =0x40F01323 @ MemConfig1 地址範圍0x4000_0000~0x4FFF_FFFF, revised設定:0x40F81313
str r1, [r0, #DMC_MEMCONFIG1] @ 0xF000_000C
補充:
為了DRAM地址的連續性,4片128MB的DDR2可以佔用地址空間0x3000_0000~0x4FFF_FFFF,
DMC0_MemConfig0: 0x3000_0000~0x37FF_FFFF
DMC1_MemConfig0: 0x3800_0000~0x3FFF_FFFF
DMC0_MemConfig1: 0x4000_0000~0x47FF_FFFF
DMC1_MemConfig1: 0x4800_0000~0x4FFF_FFFF
11. 設定PrechConfig和PwrdnConfig暫存器
ldr r1, =0xFF000000 @ PrechConfig no precharge for mem0 & mem1
str r1, [r0, #DMC_PRECHCONFIG] @ 0xF000_0014
ldr r1, =0xFFFF00FF @PwrdnConfig
str r1, [r0, #DMC_PWRDNCONFIG] @ 0xF000_0028
12. 根據AC parameters時序引數設定TimingAref, TimingRow, TimingData和TimingPower暫存器
ldr r1, =0x00000618 @TimingAref 7.8us*200MHz=1560(0x618)
str r1, [r0, #DMC_TIMINGAREF] @ 0xF000_0030
ldr r1, =0x28233287
@TimingRow @200MHz tRFC[31:24]: 127.5ns/5ns+1, tRRD[23:20]: 7.5ns/5ns+1, tRP[19:16]: 15ns/5ns+1, tRCD[15:12]: 15ns/5ns+1, RC[11:6]: 60ns/5ns+1, tRAS[5:0]: 45ns/5ns+1, revised設定:0x1B34434A
str r1, [r0, #DMC_TIMINGROW] @ 0xF000_0034
ldr r1, =0x23240304
@TimingData @200Mhz tWTR[31:28]: 7.5ns/5ns+1, tWR[27:24]:15ns/5ns+1, tRTP[23:20]: 7.5ns/5ns+1, CL[19:16]=3, reserved[15:12], WL[11:8]: RL-1=3, reserved[7:4], RL[3:0]: 4 by default, AL=4-CL=1, revised設定:0x34330304
str r1, [r0, #DMC_TIMINGDATA] @ 0xF000_0038
ldr r1, =0x09C80232
@TimingPower reserved[31:30], tFAW[29:24]: 37.5ns/5ns+1, tXSR[23:16]: 200clk, tXP[15:8]: 2clk, tCKE[7:4]: 3clk, tMRD[3:0]: 2clk
str r1, [r0, #DMC_TIMINGPOWER] @ 0xF000_003C
13. 如果需要QoS,設定QosControl0~15和QosConfig0~15暫存器
14. 等待PhyStatus0.ctrl_locked置”1”(PHY DLL locked)
find_lock_val:
ldr r1, [r0, #DMC_PHYSTATUS] @ 0xF000_0040 Load Phystatus
and r2, r1, #0x7
cmp r2, #0x7 @Loop until DLL is locked
bne find_lock_val
15. PHY DLL用於製程,電壓,溫度補償,DLL開啟更可靠,但如果頻率很低DLL off也可以正常工作,可以關閉,基於PhyStatus0.ctrl_lock_value[9:2]設定PhyControl0.ctrl_force (BIT[31:24]), 清除PhyControl0.ctrl_dll_on (BIT[1])
and r1, #0x3fc0
@ ctrl_lock_value: bit[13:4], [9:2]相當於ignore最後2bit, 即[13:6]
mov r2, r1, LSL #18
@ LSL: 左移,相當於把ctrl_lock_value這8bit的值賦值到r2的bit[31:24] (DLL Force Delay),
orr r2, r2, #0x100000 @ set bit20, PhyControl0.ctrl_inc=0x10
orr r2 ,r2, #0x1000 @ set bit12, PhyControl0.start_point=0x10
orr r1, r2, #0x3 @ set bit0&1 PhyControl0.ctrl_dll_on&ctrl_start
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
orr r1, r2, #0x1 @ set bit 0 DLL off
str r1, [r0, #DMC_PHYCONTROL0]
16. 確認上電後時鐘已經穩定200us
17. 通過DirectCmd暫存器發NOP命令,拉高CKE (DirectCmd見手冊1.4.1.5)
ldr r1, =0x07000000 @ DirectCmd chip0 Deselect
str r1, [r0, #DMC_DIRECTCMD] @ 0xF000_0010
18. 等待最小400ns
19. 通過DirectCmd暫存器發PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
20. 發EMRS2命令寫入工作引數
ldr r1, =0x00020000 @DirectCmd chip0 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
21. 發EMRS3命令寫入工作引數
ldr r1, =0x00030000 @DirectCmd chip0 EMRS3
str r1, [r0, #DMC_DIRECTCMD]
22. 發EMRS命令使能memory DLL
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]
23. 發MRS命令reset memory DLL
ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]
24. 發PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
25. 發二次Auto Refresh命令
ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]
26. 發MRS命令寫入工作引數而不reset memory DLL
ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]
27. 等待最少200個時鐘週期
28. 發EMRS命令寫入工作引數,如果沒有使用OCD校準,發EMRS命令設定OCD Calibration Default
ldr r1, =0x00010780 @DirectCmd chip0 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]
29. 發EMRS命令退出OCD校準模式並寫入工作引數
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (OCD exit)
str r1, [r0, #DMC_DIRECTCMD]
30. 如果有兩片DDR2,重新做第17步到29步
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)
31. 設定ConControl開啟auto refresh counter (BIT5)
ldr r1, =0x0FF02030 @ConControl auto refresh on, revised: 0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL] @ 0xF000_0000
32. 如果需要使用power down模式,設定MemControl暫存器
ldr r1, =0x00212400
@MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]