1:SDRAM基礎:
通過s3c2440的內存原理以及時序來理解s5pv210 SDRAM原理、時序。
首先看一下核心板內存如何連接的
可以看一下兩個內存芯片接的地址總線均為Xm1_ADDR[13:0],數據總線Xm1_DATA[15:0]、Xm1_DATA[31:16],兩個內存芯片是並聯的,當地址總線Xm1_ADDR[13:0]尋址時,
可以同時在兩個內存芯片上各獲取16位數據來組成一個32位數據,並由32位數據總線輸出。
在看下面這幅圖:下圖為每個內存芯片內部框圖:Block Diagram (128Mb x 8),從圖中可以看出:有8bank:bank0—bank1,BA0-BA2用來選擇bank的,正好可選8個。
每個bank的row尋址為14位,列尋址的位10位(行列尋址是共用14位地址總線的,通過不同的時序來加以區分,下面會詳細介紹時序),所以每個bank的大小為2的24次方bit,為16MB,
一共8個bank,總共128MB。從核心板圖上可以看出整個SDRAM,由4對16位內存芯片組成,每個內存芯片128MB,其中有兩個內存芯片並聯成32位內存,共256MB內存連接在DMC0,
另兩個內存芯片也並聯成32位內存,共256MB連接在DMC1。
2:內存芯片各引腳說明
除去上面介紹的Xm1_ADDR[13:0]做行列地址總線、Xm1_DATA[31:0]作為地址總線以外還有以下接線:
Xm1_BA[2:0]:bank address,bank選擇引腳;
Xm1_SCLK:內存時鍾;
Xm1_SCLKn:負時鍾
Xm1_RASn:行地址選擇;
Xm1_CASn:列地址選擇;
CS:片選;
CKE:命令有效時鍾;
WE:寫信號;
DQS:數據選通信號;
DQSn:數據選通負信號;
DDR SDRAM時序詳解:
待補充
3:代碼詳解
1.2.1.3
DDR2
Initialization sequence for DDR2 memory type:
1. To provide stable power for controller and memory device, the controller must assert and hold CKE to a logic low level. Then apply stable clock. Note: XDDR2SEL should be High level to hold CKE to low.
2. Set the PhyControl0.ctrl_start_point and PhyControl0.ctrl_inc bit-fields to correct value according to clock frequency. Set the PhyControl0.ctrl_dll_on bit-field to ‘1’ to turn on the PHY DLL.
3. DQS Cleaning: Set the PhyControl1.ctrl_shiftc and PhyControl1.ctrl_offsetc bit-fields to correct value according to clock frequency and memory tAC parameters.
4. Set the PhyControl0.ctrl_start bit-field to ‘1’.
5. Set the ConControl. At this moment, an auto refresh counter should be off.
6. Set the MemControl. At this moment, all power down modes should be off.
7. Set the MemConfig0 register. If there are two external memory chips, set the MemConfig1 register.
8. Set the PrechConfig and PwrdnConfig registers.
9. Set the TimingAref, TimingRow, TimingData and TimingPower registers according to memory AC parameters.
10. If QoS scheme is required, set the QosControl0~15 and QosConfig0~15 registers.
11. Wait for the PhyStatus0.ctrl_locked bit-fields to change to ‘1’. Check whether PHY DLL is locked.
12. PHY DLL compensates the changes of delay amount caused by Process, Voltage and Temperature (PVT) variation during memory operation. Therefore, PHY DLL should not be off for reliable operation. It can be off except runs at low frequency. If off mode is used, set the PhyControl0.ctrl_force bit-field to correct value according to the PhyStatus0.ctrl_lock_value[9:2] bit-field to fix delay amount. Clear the PhyControl0.ctrl_dll_on bit-field to turn off PHY DLL.
13. Confirm whether stable clock is issued minimum 200us after power on
14. Issue a NOP command using the DirectCmd register to assert and to hold CKE to a logic high level.
15. Wait for minimum 400ns.
16. Issue a PALL command using the DirectCmd register.
17. Issue an EMRS2 command using the DirectCmd register to program the operating parameters.
18. Issue an EMRS3 command using the DirectCmd register to program the operating parameters.
19. Issue an EMRS command using the DirectCmd register to enable the memory DLLs.
20. Issue a MRS command using the DirectCmd register to reset the memory DLL.
21. Issue a PALL command using the DirectCmd register.
22. Issue two Auto Refresh commands using the DirectCmd register.
23. Issue a MRS command using the DirectCmd register to program the operating parameters without resetting the memory DLL.
24. Wait for minimum 200 clock cycles.
25. Issue an EMRS command using the DirectCmd register to program the operating parameters. If OCD calibration is not used, issue an EMRS command to set OCD Calibration Default. After that, issue an EMRS command to exit OCD Calibration Mode and to program the operating parameters.
26. If there are two external memory chips, perform steps 14~25 for chip1 memory device.
27. Set the ConControl to turn on an auto refresh counter. 28. If power down modes is required, set the MemControl registers.
.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]
首先在初始化DDR之前,引入一個關於DRAM Drive Strength的概念----DRAM Drive Strength(也被稱為:driving strength),表示“DRAM驅動強度”。這個參數用來控制內存數據總線的信號強度,數值越高代表信號強度越高,增加信號強度可以提高超頻的穩定性。但是並非信號強度高就一定好。
所以,這里我們需要配置這個Drive Striegth,DDR2內存的所有線都需要配置,這里我們從地址線開始看,所有的引腳驅動強度都要設置:
設置方式:從Xm1ADDR[0:7]對應的是PM1_0寄存器,然后查找PM1_0寄存器的地址
可以看到MP1_0DRV的地址是0xE02003CC,R/W,作用用來設置驅動強度的寄存器,起始值為0xAAAA,可以看出通過設置這個寄存器,我們把Xm1ADDR[0:7]8根地址總線的驅動強度都設置為2x
同樣 Xm1ADDR[8:15]對應的是PM1_1寄存器,然后查找PM1_1寄存器的地址,地址為0xE02003EC,值設置為0xAAAA,即對應地址總線驅動強度為2x
剩余的按照上面一次類推,注意最后一個MP1_8的設置,值需要設置到MP1_8[4]即可,完成DMC0的驅動強度設置。
1. To provide stable power for controller and memory device, the controller must assert and hold CKE to a logic low level. Then apply stable clock. Note: XDDR2SEL should be High level to hold CKE to low.(為了給控制器和內存設備提供穩定的電源,控制器必須把CKE保持為邏輯低電平,然后在應用穩定的時鍾,注意:XDDR2SEL應該是邏輯高電平才能保持CKE為低。)
一般XDDR2SEL在電路設計的時候直接接到了Vcc,為高電平,所以這個不用設置看下圖,如果XDDR2SEL,接在某GPIO上的話需要設置GPIO輸出高電平才可以;
2:Set the PhyControl0.ctrl_start_point and PhyControl0.ctrl_inc bit-fields to correct value according to clock frequency. Set the PhyControl0.ctrl_dll_on bit-field to ‘1’ to turn on the PHY DLL.
根據時鍾的頻率,設置PhyControl0.ctrl_start_point and PhyControl0.ctrl_inc 字段為正確的值。
設置PhyControl0.ctrl_dll_on字段為1開啟PHY DLL。
/* 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]
根據時鍾的頻率,設置PhyControl0.ctrl_start_point and PhyControl0.ctrl_inc 字段為正確的值。
3. DQS Cleaning: Set the PhyControl1.ctrl_shiftc and PhyControl1.ctrl_offsetc bit-fields to correct value according to clock frequency and memory tAC parameters.
DQS清除:設置the PhyControl1.ctrl_shiftc and PhyControl1.ctrl_offsetc位字段,根據時鍾頻率和內存TAC參數。
ctrl_shiftc是粗條,通過控制器的DLL調整DQS的相移。(0x6 when DDR2 @200MHz)
ctrl_offsetc是精調,在ctrl_shiftc的基礎上通過控制器的DLL調整DQS的相移。
ctrl_ref 是DLL同步完成之后需要的一個延時。默認是4這設置成8
按照第2步的要求,打開PLL,將PhyControl0.ctrl_dll_on配置為1;
4. Set the PhyControl0.ctrl_start bit-field to ‘1’.
PhyControl0.ctrl_start位的值為'1'
一下幾步是執行11、12步檢查DLL

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
12. PHY DLL補償在內存操作時由PVT(Process, Voltage and Temperature,處理器、電壓和溫度)變化引起的延遲量。但是,PHY DLL不能因某些可靠的內存操作而切斷,除非是工作在低頻率下。如果關閉PHY DLL,依照PhyStatus0.ctrl_lock_value[9:2]位的值正確配置PhyControl0.ctrl_force位的值來彌補延遲量(fix delay amount)。清除PhyControl0.ctrl_dll_on位的值來關閉PHY DLL。
and r1, #0x3fc0 //取出PhyStatus0.ctrl_lock_value[9:2] mov r2, r1, LSL #18 //把r1左移18位放入r2 orr r2, r2, #0x100000 //把r2的21位置1 orr r2 ,r2, #0x1000 //r2的13位置1 orr r1, r2, #0x3 @Force Value locking //r2 0、1bit為置1放入r1 str r1, [r0, #DMC_PHYCONTROL0] //r1寫入PhyControl0
1、DQS是DLL根據clk產生的信號,這個信號也被稱之為數據眼,DQS的主要作用就是告訴控制器何時讀/寫數據。確保數據的穩定接收和發送。
小節:
到了這里,所以關於DLL的部分就配置完了,主要用到的寄存器只有3個:PhyControl0,PhyControl1,和PhyStatus0。
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
12步之后再才開始之前的第5步:
5. Set the ConControl. At this moment, an auto refresh counter should be off.
設置ConControl,此時應關閉自刷新計數器。
ldr r1, =0x0FFF2010 @ConControl auto refresh off str r1, [r0, #DMC_CONCONTROL]
其中aref_en為0時就表示關閉自刷新計數器。
rd_fetch的設置是針對FIFO的讀取時間的,設置成2更保險一點~~(默認值是1)
注意:這個寄存器中有一些有用的值需要注意一下
這兩個bit位表示dmc0、dmc1、是否接內存芯片,根據實際情況選擇。
6. Set the MemControl. At this moment, all power down modes should be off.
配置MemControl比較重要的就是以下這幾位,突發長度,chip個數,總線寬度,內存類型。
ldr r1, =DMC0_MEMCONTROL //0x00212400 @MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off str r1, [r0, #DMC_MEMCONTROL]
這里注意一些有用信息:BL為4字節,1 chip、32位 DDR2內存。
7. Set the MemConfig0 register. If there are two external memory chips, set the MemConfig1 register.
如果有兩個外部內存芯片,設置 MemConfig1 register.
ldr r1, =DMC0_MEMCONFIG_0 // //#define DMC0_MEMCONFIG_0 0x20F01323 @MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed str r1, [r0, #DMC_MEMCONFIG0]
這里的每一個bit都比較重要,一個個解釋一下:
芯片內存的排列方式:交互的;
2、chip_mask 確定一個chip的映射范圍大小。1表示屏蔽,0表示不屏蔽。
如chip_mask = F0表示屏蔽高4位,那么映射大小就是:
0X0~0X0FFF_FFFF,也就是256M
如chip_mask = E0表示屏蔽高3位,那么映射大小就是:
0X0~0X1FFF_FFFF,也就是512M,我們這里設置的是F0,內存為256MB
1、chip_base DRR的映射地址,默認0x2000_0000
// #define DMC0_MEMCONFIG_1 0x30F00312 ldr r1, =DMC0_MEMCONFIG_1 @MemConfig1 str r1, [r0, #DMC_MEMCONFIG1]
由於沒有用到DMC0_MEMCONFIG_1 ,直接設置為默認值即可。
step8. Set the PrechConfig and PwrdnConfig registers.
現在可以開始配置PrechConfig預充電寄存器和 Pwrdown寄存器,但是damo程序中把 PwrdnConfig registers.的
配置放到了最后一步,所以這里先只講述PrechConfig的配置。
ldr r1, =0xFF000000 @PrechConfig
str r1, [r0, #DMC_PRECHCONFIG]
這個寄存器用的其實是默認值,具體位的含義可以參考手冊.
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
step9. Set the TimingAref, TimingRow, TimingData and TimingPower registers according to memory AC parameters.
9.1 TimingAref
#define DMC0_TIMINGA_REF 0x00000618
ldr r1, =DMC0_TIMINGA_REF @TimingAref
str r1, [r0, #DMC_TIMINGAREF]
因為ddr是需要不斷的刷新保持數據的,而這個刷新間隔不能太長,一般ddr這個間隔時間參數就是7.8us,具體時間查看ddr手冊。也就是說最長7.8us必須刷新一次。我們不能直接把7.8us告訴arm,必須轉換成時鍾周期數告訴給arm。及把時鍾周期數放到TimingAref.t_refi字段即可。那么周期如何算?首先你得知道此時提供MCD的時鍾是多大,比如是133M,那么周期數就是7.8 us * 133 MHz = 1038 = 0x40E;如果時鍾是200M那么周期數就是7.8 us * 200MHz = 1,560= 0x618;
9.2 TimingRow,這個寄存器主要是配置一些ddr時序參數了,這些參數需要到具體型號的ddr手冊中去一個個的找~~(當然同樣,時間要轉換為時鍾周期數)
#define DMC0_TIMING_ROW 0x28233287 // TimingRow for @200MHz
ldr r1, =DMC0_TIMING_ROW @TimingRow for @200MHz
str r1, [r0, #DMC_TIMINGROW]
9.3 TimingData 這個寄存器和上面寄存器一樣,需要到具體型號的ddr手冊中去一個個的找
其中需要注意的是cl,也就是CAS,
ddr手冊中明確說明CAS可以配置為3,4,5,6這幾個時鍾周期。值得注意的是,目前我們配置的ddr控制器的CAS,之后還需配置ddr芯片本身的CAS。
所以,我們必須確保這兩個CAS一致!
還有就是對於DDR2而言,所以wl這參數不用配置。但是對於低功耗的ddr就必須配置了。
#define DMC0_TIMING_DATA 0x23240304 // TimingData CL=3
ldr r1, =DMC0_TIMING_DATA @TimingData CL=3
str r1, [r0, #DMC_TIMINGDATA]
9.4 TimingPower 也是一樣
#define DMC0_TIMING_PWR 0x09C80232 // TimingPower
ldr r1, =DMC0_TIMING_PWR @TimingPower
str r1, [r0, #DMC_TIMINGPOWER]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
step10 If QoS scheme is required, set the QosControl0~15 and QosConfig0~15 registers.
現在不用Qos,跳過了~~。。。
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
step11 and step12 被移到了第5步之前了~~
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
step13. Confirm whether stable clock is issued minimum 200us after power on
由於step11 and step12被提到前面了,所以現在可以不等了~~
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
step14~26 這些都是配置ddr芯片(而不是ddr控制器了),都是通過XXX寄存器向ddr芯片發送命令。
step14. Issue a NOP command using the DirectCmd register to assert and to hold CKE to a logic high level.
ldr r1, =0x07000000 @DirectCmd chip0 Deselect
str r1, [r0, #DMC_DIRECTCMD]
發送nop指令將CKE置高
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
step15. Wait for minimum 400ns.
因為此前CKE一直為高,所以這里無需再等。
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
step16. Issue a PALL command using the DirectCmd register.
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
step17. Issue an EMRS2 command using the DirectCmd register to program the operating p
該寄存器作用不大,全部置0
ldr r1, =0x00020000 @DirectCmd chip0 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
18. Issue an EMRS3 command using the DirectCmd register to program the operating p
ldr r1, =0x00030000 @DirectCmd chip0 EMRS3
str r1, [r0, #DMC_DIRECTCMD]
以上四個步驟對應下圖:
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
19. Issue an EMRS command using the DirectCmd register to enable the memory DLLs
這說的EMRS 就是EMRS1.
這里感覺主要就是A10設置為1,禁止了差分的DQS,而使用單端。
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
20. Issue a MRS command using the DirectCmd register to reset the memory DLL.
這一步配置MRS寄存器就很重要了~~
A8為1,是因為該步驟說明中明確指明要——reset the memory DLL.
ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
21. Issue a PALL command using the DirectCmd register.
再次發送一個PALL指令,和16步一樣
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
22. Issue two Auto Refresh commands using the DirectCmd register.
連續發送兩個 Auto Refresh指令
ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
23. Issue a MRS command using the DirectCmd register to program the operating para
the memory DLL.
該步和第20步相同,也是寫MRS,唯一的不同是A8這個為不同此時置位1,也就是不再復位DLL。
ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
24. Wait for minimum 200 clock cycles.
damo程序中並未等待~~
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
25. Issue an EMRS command using the DirectCmd register to program the operating pa
calibration is not used, issue an EMRS command to set OCD Calibration Default. Aft
command to exit OCD Calibration Mode and to program the operating parameters.
通過寫兩次EMRS1配置OCD校准,可以看到第一次將OCD_Corr寫成111,之后又寫成000
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]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
26. If there are two external memory chips, perform steps 14~25 for chip1 memory device.
如果DMC控制的是兩個chip那么還需要配置一次chip1,就是把14~25重復一遍,只不過cmd_chip這個位要置1.
也就是說,到了這一步,關於ddr芯片的配置全部結束了。
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]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
27. Set the ConControl to turn on an auto refresh counter.
到了這一步再次回到ddr控制器的配置。
這一步和第5步只有一處不同,就是aref_en,這里開啟了ddr控制器的自刷新功能。
ldr r1, =0x0FF02030 @ConControl auto refresh on
str r1, [r0, #DMC_CONCONTROL]
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
28. If power down modes is required, set the MemControl registers.
還記得第8部嗎? Set the PrechConfig and PwrdnConfig registers. 當時damo只配置了PrechConfig 而沒有配置PwrdnConfig ,而在這里
damo程序對PwrdnConfig 進行了配置。但基本就是按默認值配置的。
ldr r1, =0xFFFF00FF @PwrdnConfig
str r1, [r0, #DMC_PWRDNCONFIG]
程序再次設置了MemControl,這和第6步完全相同。這個步驟的本意是如果需要power down modes那么就去設置MemControl去使能相應的為,但是damo程序不想
power down modes這個功能,所以即使配置了PrechConfig也只是“做個樣子”。
MemControl
ldr r1, =0x00202400 @MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]