S3C6410,Tiny6410,Mini6410,MoblieDDR內(nèi)存驅(qū)動
S3C6410內(nèi)存控制器是采用的PL340內(nèi)存控制芯片。AMBA APB3.0接口協(xié)議規(guī)定,可以通過編程將AXI從總線接口和APB主總線接口進行橋接,實現(xiàn)二者總線上的數(shù)據(jù)的傳輸。
本文引用地址:http://www.ex-cimer.com/article/201611/319033.htmDRAM控制器可以通過配置兼容SDRAM類型芯片。通過向DRAM控制器中PL340寫入內(nèi)存芯片配置參數(shù),內(nèi)存時序,來控制內(nèi)存工作。
DRAM控制器可以直接從SDRAM或DRAM接收一個控制命令。通過將操作命令寫入direct_cmd寄存器,操作SDRAM進行對應(yīng)操作。通過向memc_cmd寄存器寫入狀態(tài)模式命令,使DRAM控制器進入對應(yīng)的工作模式。例如:向direct_cmd寄存器寫入:Prechargeall’,‘Autorefresh’,‘NOP’,and ‘MRS’ 等命令,可以讓SDRAM芯片分別執(zhí)行不同操作,向memc_cmd寄存器寫入一些狀態(tài)命令可以讓SDRAM芯片進入’Config’, ‘Ready’, and ‘Low_power’等工作模式。
DRAM控制器支持兩種節(jié)能模式。當(dāng)SDRAM處于不活動狀態(tài)并且持續(xù)一定的時鐘周期時,DRAM控制器會自動將SDRAM進入預(yù)充電節(jié)能模式或正常節(jié)能模式下以降低系統(tǒng)功耗。當(dāng)驅(qū)動操作DRAM控制器進入對應(yīng)的STOP(停止),Deep Stop(深度睡眠),Sleep Mode(睡眠)等模式時,SDRAM芯片進入自刷新的節(jié)能模式。
l 支持SDR SDRAM,Mobile SDR SDRAM,DDR SDRAM和Mobile DDR SDRAM類型芯片
l 支持兩個內(nèi)存芯片
l 支持64位的AMBA AXI總線類型
l 支持16位、64位內(nèi)存總線
n 存儲器接口1:支持16位DDR SDRAM和Mobile DDR SDRAM類型芯片
支持32位DDR SDRAM,Mobile DDR SDRAM,Mobile SDR SDRAM和SDR SDRAM類型芯片
不支持16位Mobile SDR SDRAM和SDR SDRAM類型芯片
l 地址空間:存儲器接口1支持最多2Gb地址空間
l 支持正常節(jié)能模式和預(yù)充電的節(jié)能模式
l 數(shù)據(jù)傳輸?shù)脱舆t特性
l 外部存儲器總線優(yōu)化
l 通過設(shè)置SFR寄存器支持選擇外部存儲器選型
l 通過SFR寄存器配置存儲器的時序
l 支持擴展MRS指令集
l 工作電壓:存儲器接口1: 1.8V,2.5V
2. SDRAM類型內(nèi)存接口
DRAM控制器支持最多兩個相同類型的內(nèi)存芯片,每個芯片最大容量256M。所有芯片共享相同引腳(時鐘使能引腳和片選引腳除外),如表1-1所示給出了DRAM控制器的外部存儲器引腳配置信息。
3. SDRAM初始化
在系統(tǒng)上電后,必須通過軟件配置SDRAM接入DRAM控制器并且初始化DRAM控制器,下面給出DDR、MOBILE DDR SDRAM的初始化流程。
a) 向mem_cmd寄存器寫入0b10,使其進入NOP工作狀態(tài)
b) 向mem_cmd寄存器寫入0b00,使其進入Prechargeall(整片預(yù)充電)工作狀態(tài)
c) 向mem_cmd寄存器寫入0b11,使其進入Autorefresh(自刷新)工作狀態(tài)
d) 再次向mem_cmd寄存器寫入0b11,使其進入Autorefresh(自刷新)工作狀態(tài)
e) 向mem_cmd寄存器寫入0b10,使其進入MRS工作狀態(tài),并且地址空間內(nèi)的EMRS必須置位
f) 再次向mem_cmd寄存器寫入0b10,使其進入MRS工作狀態(tài),并且地址空間內(nèi)的MRS必須置位
4. DRAM寄存器
1) DRAM控制器狀態(tài)寄存器(P1MEMSTAT)
P1MEMSTAT | 位 | 描述 | 初始值 |
保留 | [31:9] | - | - |
芯片數(shù)量 | [8:7] | 內(nèi)存控制器支持的芯片最大數(shù)量: 01 = 2片 6410只支持2片芯片,初始化為只讀的01 | 01 |
芯片類型 | [6:4] | 內(nèi)存控制器支持的芯片類型: 100 = MSDR/SDR/MDDR/DDR中任一類型 | 100 |
芯片位寬 | [3:2] | 接入內(nèi)存芯片的位寬: 00 = 16位 01 = 32位 10 = 保留 11 = 保留 | 01 |
控制器狀態(tài) | [1:0] | DRAM控制器狀態(tài): 00 = Config配置狀態(tài) 01 = Ready就緒狀態(tài) 10 = Pause暫停狀態(tài) 11 = Low-Power節(jié)能狀態(tài) | 00 |
實際上,讀到的有用信息就是Controller Status和Memory width。
2) DRAM控制器命令寄存器(P1MEMCCMD)
P1MEMCCMD | 位 | 描述 | 初始值 |
保留 | [31:3] | 未定義,寫入0 | - |
Memc_cmd | [2:0] | 設(shè)置內(nèi)存控制器的工作狀態(tài): 000 = Go 001 = sleep 010 = wakeup 011 = Pause 100 = Configure 101~111 = 保留 |
最開始應(yīng)該配置為0x4,是處于Configure狀態(tài)。在配置完所有的DRAM之后,將該寄存器設(shè)置為0x0,處于運行狀態(tài)。
3) 直接命令寄存器(P1DIRECTCMD)
P1DIRECTCMD | 位 | 描述 | 初始值 |
保留 | [31:23] | 未定義,寫入0 | |
擴展內(nèi)存命令 | [22] | (見下表) | |
芯片號 | [21:20] | 映射到外部存儲芯片地址的位 | |
命令 | [19:18] | 具體命令(見下表) | |
Bank地址 | [17:16] | 當(dāng)以MRS或EMRS命令訪問時,映射到外部存儲器的Bank地址位 | |
[15:14] | 未定義,寫入0 | ||
地址線0~13 | [13:0] | 當(dāng)以MRS或EMRS命令訪問時,映射到外部存儲器的內(nèi)存地址位 |
用于發(fā)送命令到DRAM和訪問DRAM中的MRS和EMRS寄存器。通過該寄存器初始化DRAM,先設(shè)置為NOP模式,然后設(shè)置為PrechargeAll進行充電,然后設(shè)置EMRS和MRS寄存器,一般是這么一個流程。具體的要參見你所使用的DRAM的datasheet。
4) 內(nèi)存配置寄存器(P1MEMCFG)
P1MEMCFG | 位 | 描述 | 初始值 |
保留 | [31:23] | 未定義 | |
啟動芯片 | [22] | 使能下面數(shù)量的芯片開始執(zhí)行刷新操作: 00 = 1芯片 01 = 2芯片 10/11 = 保留 | 00 |
QoS master位 | [20:18] | 設(shè)置QoS值: 000 = ARID[3:0] 001= ARID[4:1] 010 = ARID[5:2] 011 = ARID[6:3] 100 = ARID[7:4] 101~111 = 保留 | 000 |
內(nèi)存突發(fā)訪問 | [17:15] | 在內(nèi)存讀寫時,設(shè)置突發(fā)訪問數(shù)據(jù)的數(shù)量: 000 = 突發(fā)訪問1個數(shù)據(jù) 001 = 突發(fā)訪問2個數(shù)據(jù) 010 = 突發(fā)訪問4個數(shù)據(jù) 011 = 突發(fā)訪問8個數(shù)據(jù) 100 = 突發(fā)訪問16個數(shù)據(jù) 101~111 = 保留 該值必須通過DIRECTORYCMD寄存器,寫入到內(nèi)存的模式寄存器中,并且數(shù)據(jù)必須匹配 | 010 |
Bank地址 | [17:16] | 當(dāng)以MRS或EMRS命令訪問時,映射到外部存儲器的Bank地址位 | |
Stop_mem_clock | [14] | 當(dāng)停止芯片時鐘,不允許訪問內(nèi)存數(shù)據(jù)時,置位 | 0 |
自動節(jié)能 | [13] | 當(dāng)該位置位時,芯片自動進入節(jié)能狀態(tài) | 0 |
關(guān)閉芯片延遲時間 | [12:7] | 當(dāng)關(guān)閉內(nèi)存芯片時,延遲的時鐘個數(shù) | 000000 |
自動預(yù)充電位 | [6] | 內(nèi)存地址中自動預(yù)充電位的位置: 0 = ADDR[10] 1 = ADDR[8] | 0 |
行地址位數(shù) | [5:3] | AXI地址線上的行地址位數(shù): 000 = 11位 001 = 12位 010 = 13位 011 = 14位 100 = 15位 101= 16位 | 100 |
列地址位數(shù) | [2:0] | AXI地址線上的列地址位數(shù): 000 = 8位 001 = 9位 010 = 10位 011 = 11位 100 = 12位 | 000 |
參考DRAM的datasheet。
5) 內(nèi)存刷新時間寄存器(P1REFRESH)
P1REFRESH | 位 | 描述 | 初始值 |
[31:15] | - | ||
刷新時間 | [14:0] | 內(nèi)存刷新時鐘周期數(shù) | 0xA60 |
6) CAS 延遲寄存器(P1CASLAT)
P1CASLAT | 位 | 描述 | 初始值 |
[31:4] | - | - | |
CAS延遲 | [3:1] | 列地址選通延遲內(nèi)存時鐘周期數(shù) | 0xA60 |
CAS HALF周期 | [0] | 設(shè)置CAS延遲數(shù)是否為半個內(nèi)存時鐘周期 0 = 以[3:1]設(shè)置數(shù)為CAS延遲時鐘周期 1 = 以[3:1]設(shè)置數(shù)的一半為CAS延遲時鐘周期 | 0 |
參考DRAM的datasheet。
下面13個寄存器用于DRAM操作中所需時間和延時寄存器,具體可以參考PL340文檔。
7) T_DQSS寄存器(P1T_DQSS)
P1T_DQSS | 位 | 描述 | 初始值 |
[31:2] | - | - | |
t_DQSS | [1:0] | 寫入DQS的時鐘周期 | 1 |
8) T_MRD寄存器(P1T_MRD)
P1T_MRD | 位 | 描述 | 初始值 |
[31:7] | - | - | |
t_ MRD | [6:0] | 設(shè)置模式寄存器命令時間(內(nèi)存時鐘周期為單位) | 0x02 |
9) T_RAS寄存器(P1T_RAS)
P1T_RAS | 位 | 描述 | 初始值 |
[31:4] | - | - | |
t_RAS | [3:0] | 設(shè)置行地址選通到預(yù)充電操作延遲時間(內(nèi)存時鐘周期為單位) | 0x7 |
10) T_RC寄存器(P1T_RC)
P1T_RC | 位 | 描述 | 初始值 |
[31:4] | - | - | |
t_RC | [3:0] | 設(shè)置激活內(nèi)存Bank x到激活另外一個Bank x操作的延遲時間(內(nèi)存時鐘周期為單位) | 0xB |
11) T_RCD寄存器(P1T_RCD)
P1T_RCD | 位 | 描述 | 初始值 |
[31:6] | - | - | |
Scheduled_RCD | [5:3] | 設(shè)置t_RCD-3 | 011 |
t_RCD | [2:0] | 設(shè)置RAS到CAS操作的最小延遲時間(內(nèi)存時鐘周期為單位) | 101 |
12) T_RFC寄存器(P1T_RFC)
P1T_RFC | 位 | 描述 | 初始值 |
[31:10] | - | - | |
Scheduled_RFC | [9:5] | 設(shè)置t_RFC-3 | 0x10 |
t_RFC | [4:0] | 設(shè)置自動刷新命令操作延遲時間(內(nèi)存時鐘周期為單位) | 0x12 |
13) T_RP寄存器(P1T_RP)
P1T_RP | 位 | 描述 | 初始值 |
[31:6] | - | - | |
Scheduled_RP | [5:3] | 設(shè)置t_RP-3 | 011 |
t_RFC | [2:0] | 設(shè)置預(yù)充電到RAS操作的延遲時間(內(nèi)存時鐘周期為單位) | 101 |
14) T_RRD寄存器(P1T_RRD)
P1T_ RRD | 位 | 描述 | 初始值 |
[31:4] | - | - | |
t_RRD | [3:0] | 設(shè)置激活內(nèi)存Bank x到激活內(nèi)存Bank y操作的延遲時間(內(nèi)存時鐘周期為單位) | 0x2 |
15) T_WR寄存器(P1T_WR)
P1T_ WR | 位 | 描述 | 初始值 |
[31:3] | - | - | |
t_WR | [2:0] | 設(shè)置寫入數(shù)據(jù)到預(yù)充電操作的延遲時間(內(nèi)存時鐘周期為單位) | 011 |
16) T_WTR寄存器(P1T_WTR)
P1T_ WTR | 位 | 描述 | 初始值 |
[31:3] | - | - | |
t_WTR | [2:0] | 設(shè)置寫入數(shù)據(jù)到讀取數(shù)據(jù)操作的延遲時間(內(nèi)存時鐘周期為單位) | 011 |
17) T_XP寄存器(P1T_XP)
P1T_ XP | 位 | 描述 | 初始值 |
[31:8] | - | - | |
t_XP | [7:0] | 設(shè)置退出關(guān)閉電源命令的延遲時間(內(nèi)存時鐘周期為單位) | 0x1 |
18) T_XSR寄存器(P1T_XSR)
P1T_ XSR | 位 | 描述 | 初始值 |
[31:8] | - | - | |
t_XSR | [7:0] | 設(shè)置退出自刷新命令的延遲時間(內(nèi)存時鐘周期為單位) | 0xA |
19) T_ESR寄存器(P1T_ESR)
P1T_ ESR | 位 | 描述 | 初始值 |
[31:8] | - | - | |
t_ESR | [7:0] | 設(shè)置自刷新命令的延遲時間(內(nèi)存時鐘周期為單位) | 0x14 |
內(nèi)存初始化代碼:
(開發(fā)環(huán)境為ADS1.2)
- MEM_SYS_CFGEQU0x7e00f120
- DMC1_BASEEQU0x7e001000
- INDEX_DMC_MEMC_STATUSEQU0x0
- INDEX_DMC_MEMC_CMDEQU0x4
- INDEX_DMC_DIRECT_CMDEQU0x08
- INDEX_DMC_MEMORY_CFGEQU0x0c
- INDEX_DMC_REFRESH_PRDEQU0x10
- INDEX_DMC_CAS_LATENCYEQU0x14
- INDEX_DMC_T_DQSSEQU0x18
- INDEX_DMC_T_MRDEQU0x1c
- INDEX_DMC_T_RASEQU0x20
- INDEX_DMC_T_RCEQU0x24
- INDEX_DMC_T_RCDEQU0x28
- INDEX_DMC_T_RFCEQU0x2c
- INDEX_DMC_T_RPEQU0x30
- INDEX_DMC_T_RRDEQU0x34
- INDEX_DMC_T_WREQU0x38
- INDEX_DMC_T_WTREQU0x3c
- INDEX_DMC_T_XPEQU0x40
- INDEX_DMC_T_XSREQU0x44
- INDEX_DMC_T_ESREQU0x48
- INDEX_DMC_MEMORY_CFG2EQU0x4C
- INDEX_DMC_CHIP_0_CFGEQU0x200
- INDEX_DMC_CHIP_1_CFGEQU0x204
- INDEX_DMC_CHIP_2_CFGEQU0x208
- INDEX_DMC_CHIP_3_CFGEQU0x20C
- INDEX_DMC_USER_STATUSEQU0x300
- INDEX_DMC_USER_CONFIGEQU0x304
- AREALOW_INIT,CODE,READONLY
- ENTRY
- EXPORTmem_init
- mem_init
- ldrr0,=MEM_SYS_CFG;Memorysussystemaddress0x7e00f120
- movr1,#0xd;Xm0CSn2=NFCONCS0設(shè)置NANDFlash為存儲器
- strr1,[r0]
- ldrr0,=DMC1_BASE;DMC1baseaddress0x7e001000
- ;memc_cmd:010wakeup
- ;喚醒內(nèi)存
- ldrr1,=0x04
- strr1,[r0,#INDEX_DMC_MEMC_CMD]
- ;Refreshperiod=((Startup_HCLK/1000*DDR_tREFRESH)-1)/1000000->DDR_tREFRESH7800ns
- ;HCLK=133MHz
- ;DDR內(nèi)存規(guī)格規(guī)定,電容的電荷存儲上限時間為64ms,而刷新操作每次是針對
- ;一行進行的,即每一行的刷新時間為64ms,而內(nèi)存芯片中一定數(shù)量的行
- ;以L-Bank表示(見內(nèi)存工作原理與物理特性),每個L-Bank有8192行(見內(nèi)存硬件手冊)
- ;因此對L-Bank的刷新操作應(yīng)該在64ms/8192=7813us時間內(nèi)進行一次
- ;而MDDR工作在133MHz時,其一個時鐘周期為1/133M,那么一次L-Bank刷新
- ;時間需要7.8us/1/133M個時鐘周期,即有下面的公式:
- ;Refresh_Count=tREFRESH*HCLK(MHz)/1000
- ;tREFRESH=7813HCLK=133Refresh_Count=1039
- ldrr1,=1039;DMC_DDR_REFRESH_PRD
- strr1,[r0,#INDEX_DMC_REFRESH_PRD]
- ;CAS_Latency=DDR_CASL<<1->DDR_CASL3
- ldrr1,=6;DMC_DDR_CAS_LATENCY
- strr1,[r0,#INDEX_DMC_CAS_LATENCY]
- ;t_DQSS(clockcycles)
- ldrr1,=1;DMC_DDR_t_DQSS
- strr1,[r0,#INDEX_DMC_T_DQSS]
- ;T_MRD(clockcycles)
- ldrr1,=2;DMC_DDR_t_MRD
- strr1,[r0,#INDEX_DMC_T_MRD]
- ;T_RAS(clockcycles)
- ldrr1,=7;DMC_DDR_t_RAS
- strr1,[r0,#INDEX_DMC_T_RAS]
- ;T_RCActiveBankxtoActiveBankxdelay(clockcycles)
- ldrr1,=10;DMC_DDR_t_RC
- strr1,[r0,#INDEX_DMC_T_RC]
- ;T_RCDRAStoCADdelay(clockcycles)
- ldrr1,=4;DMC_DDR_t_RCD
- ldrr2,=8;DMC_DDR_schedule_RCD
- orrr1,r1,r2
- strr1,[r0,#INDEX_DMC_T_RCD]
- ;T_RFCAutoRefresh(clockcycles)
- ldrr1,=11;DMC_DDR_t_RFC
- ldrr2,=256;DMC_DDR_schedule_RFC
- orrr1,r1,r2
- strr1,[r0,#INDEX_DMC_T_RFC]
- ;T_RPPrechargetoRASdelay(clockcycles)
- ldrr1,=4;DMC_DDR_t_RP
- ldrr2,=8;DMC_DDR_schedule_RP
- orrr1,r1,r2
- strr1,[r0,#INDEX_DMC_T_RP]
- ;T_RRDActiveBankxtoActiveBankydelay(clockcycles)
- ldrr1,=3;DMC_DDR_t_RRD
- strr1,[r0,#INDEX_DMC_T_RRD]
- ;T_WRWritetoprechargedelay(clockcycles)
- ldrr1,=3;DMC_DDR_t_WR
- strr1,[r0,#INDEX_DMC_T_WR]
- ;T_WTRWritetoReaddelay(clockcycles)
- ldrr1,=2;DMC_DDR_t_WTR
- strr1,[r0,#INDEX_DMC_T_WTR]
- ;T_XPExitPowerdown(clockcycles)
- ldrr1,=2;DMC_DDR_t_XP
- strr1,[r0,#INDEX_DMC_T_XP]
- ;T_XSRExitselfrefresh(clockcycles)
- ldrr1,=17;DMC_DDR_t_XSR
- strr1,[r0,#INDEX_DMC_T_XSR]
- ;T_ESRSelfRefresh(clockcycles)
- ldrr1,=17;DMC_DDR_t_ESR
- strr1,[r0,#INDEX_DMC_T_ESR]
- ;MemoryConfigurationRegister
- ldrr1,=0x40010012;DMC1_MEM_CFG
- strr1,[r0,#INDEX_DMC_MEMORY_CFG]
- ldrr1,=0xb41;DMC1_MEM_CFG2
- strr1,[r0,#INDEX_DMC_MEMORY_CFG2]
- ldrr1,=0x150f8;DMC1_CHIP0_CFG
- strr1,[r0,#INDEX_DMC_CHIP_0_CFG]
- ldrr1,=0;DMC_DDR_32_CFG
- strr1,[r0,#INDEX_DMC_USER_CONFIG]
- ;ThefollowsisaccordingtotheDatasheetinitializationsequence
- ;DMC0DDRChip0configurationdirectcommandreg
- ldrr1,=0x0c0000;DMC_NOP0
- strr1,[r0,#INDEX_DMC_DIRECT_CMD]
- ;PrechargeAll
- ldrr1,=0;DMC_PA0
- strr1,[r0,#INDEX_DMC_DIRECT_CMD]
- ;AutoRefresh2time
- ldrr1,=0x40000;DMC_AR0
- strr1,[r0,#INDEX_DMC_DIRECT_CMD]
- strr1,[r0,#INDEX_DMC_DIRECT_CMD]
- ;MRS
- ldrr1,=0xa0000;DMC_mDDR_EMR0
- strr1,[r0,#INDEX_DMC_DIRECT_CMD]
- ;ModeReg
- ldrr1,=0x80032;DMC_mDDR_MR0
- strr1,[r0,#INDEX_DMC_DIRECT_CMD]
- ;EnableDMC1
- movr1,#0x0
- strr1,[r0,#INDEX_DMC_MEMC_CMD]
- check_dmc1_ready
- ldrr1,[r0,#INDEX_DMC_MEMC_STATUS]
- movr2,#0x3
- andr1,r1,r2
- cmpr1,#0x1
- bnecheck_dmc1_ready
- nop
- movpc,lr
- END
評論