S5PV210裸机之SDRAM

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

11. 等待PhyStatus0.ctrl_locked位变为'1'。检查是否PHY 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的配置。

971ecd99-05b3-4663-992e-a49add69b4bc[4]

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

706d5a7e-e859-4949-ba6e-d7fb295735cc[4]

d4b36233-9c73-4136-ab92-02cc16d7e186[4]

#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手册中去一个个的找~~(当然同样,时间要转换为时钟周期数)

98945e96-837d-4d64-8bd0-720eae3ff7d9[4]

#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手册中去一个个的找

74871ad7-031a-4d29-8faa-dea916e24d8f[4]

其中需要注意的是cl,也就是CAS,

281bf73e-e649-47ae-9615-560fb89be812[4]

ddr手册中明确说明CAS可以配置为3,4,5,6这几个时钟周期。值得注意的是,目前我们配置的ddr控制器的CAS,之后还需配置ddr芯片本身的CAS。

所以,我们必须确保这两个CAS一致!

还有就是对于DDR2而言e6c2e3fe-8209-42f1-a266-71a66e520e1e[4],所以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 也是一样

6a47a8dc-6292-4ecc-9ce8-e9ecc8e8a9da[4]

#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

b357a2ac-405c-4602-9285-ef9554c681f8[4]

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

7ba48b2a-5907-4c0d-ae40-5aae0561e910[4]

ldr r1, =0x00030000 @DirectCmd chip0 EMRS3

str r1, [r0, #DMC_DIRECTCMD]

以上四个步骤对应下图:

57ed1770-cd14-4c7b-919a-27c8e10998fd[6]

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

19. Issue an  EMRS  command using the DirectCmd register to enable the memory DLLs

这说的EMRS 就是EMRS1.

5685825b-7be9-40ff-a1f5-8845c79a8952[4]

15a56d8e-3690-4cf1-85bc-0b50694ff19b[4]

这里感觉主要就是A10设置为1,禁止了差分的DQS,而使用单端。

8f36402a-48aa-4375-b93e-6cf6ef3c7a18[4]

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寄存器就很重要了~~

dfc134bf-056b-4da3-95d7-033f7e2fce5c[4]

A8为1,是因为该步骤说明中明确指明要——reset the memory DLL.

3c4a677f-9ffe-4926-ae4e-29da4ed4295b[4]

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]

92df4231-a092-46ce-af42-16c49aed4190[4]

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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.

7d09843e-6e8b-41e6-ab3f-276fb63c4d41[4]

通过写两次EMRS1配置OCD校准,可以看到第一次将OCD_Corr写成111,之后又写成000

113a6704-92ca-4b60-9973-eaac9690fd70[4]

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控制器的自刷新功能。

292ebdb4-6fd3-4f60-82a5-ad0040dee742[4]

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 进行了配置。但基本就是按默认值配置的。

0d530da7-b2f8-42af-94e3-e155cb5a4273[4]

ldr r1, =0xFFFF00FF @PwrdnConfig

str r1, [r0, #DMC_PWRDNCONFIG]

程序再次设置了MemControl,这和第6步完全相同。这个步骤的本意是如果需要power down modes那么就去设置MemControl去使能相应的为,但是damo程序不想

power down modes这个功能,所以即使配置了PrechConfig也只是“做个样子”。

50741f46-e3b9-4d57-b5a0-8c33db30603e[4]

e2ae71c9-6610-402e-99a8-61bf828c47c3[4]

e7da02ae-c57a-4d46-aea7-adf7d958f280[4]

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]

猜你喜欢

转载自blog.csdn.net/lushoumin/article/details/82111194