Home » 朱老师嵌入式 » SDRAM

SDRAM

编 辑:Y ┊ 时 间:2022年04月10日 ┊ 访问: 23 次

DDR (SDRAM)

特性

SDRAM 同步动态随机存取内存(synchronous dynamic random-access memory,简称SDRAM)是有一个同步接口的动态随机存取内存(DRAM)。

ddr是一个内存名称,意思即双倍速率同步动态随机存储器,是内存的其中一种。

DDR 就是DDR、SDRAM ,是SDRAM的升级版(DDR:双倍速率的SDRAM)

SDRAM的特性(容量大、价格低、掉电易失性、随机读写、总线式访问)

SDRAM/DDR都属于动态内存(相当于静态内容SRAM),都需要先运行一段初始化代码来初始化才能使用类似于SDRAM和SRAM的区别,还有NorFlash和NandFlash(硬盘)这两个。

差异

SRAM上电就可以使用,SDRAM需要初始化

NorFlash 上电就可以使用,NandFlash需要初始化

正因为硬件本身特性有限制,所以才导致启动代码比较怪异、复杂。

而研究逻辑是为了研究uboot

SDRAM在系统中属于soc外接设备(外部外设。以前说过随着半导体技术发展,很多东西都逐渐集成到soC内部去
了。现在还长期在外部的一般有: flash、 SDRAM/DDR、 网卡芯片如DM9000、音频Codec,现在有些芯片也试图把这几个集成进去,做成真正的单芯片解决方案。)

对于我们写程序来说,放里面放外面没区别。

SDRAM通过地址总线和数据总线接口(总线接口)来与Soc通信。

全球做SDRAM的厂商不多,二线厂家做的产品参数都是向一线厂家(三星、KingSton)看起,目的就是兼容一线厂家的设计,然后让在意成本的厂商选择他的内存芯片替代一线厂家的内存芯片。

手册查看内存信息

K4T1G164QE:

K表示三星产品,4表示是DRAM, T表示产品号码,1G表示容量(1Gb, 等于128MB,我们开发板x210上一-共用了4片相同的内存,所以总容量是128x4=512MB)

16表示单芯片是16位的,4表示4个bank,Q:1.8V

三星官方的数据手册上其实没有芯片相关的参数设置信心,都是芯片选型与外观封装方面的信息,选型是给产品经理来看的,封装和电压等信息是给硬件工程师看的。软件工程师最关注的是工作参数信息,但是数据手册没有。

读手册

24373-faa1b9e2b07.png

如果是SROM/NAND/ONENAND则接port0

如果是DDR2/mDDR/mDDR则接port1/port2

对比手册:

56241-eukm5p8dji.png34587-cykc4sajik6.png

原理图中每个DDR端口都由3类总线构成:地址总线( Xmn ADDRO~XMnADDR13共1 4根地址总线) +控制总线.. (. 中间部分自己看原理图)... +数据总线(Xmn DATAO~XMnDATA31共32根数据线)

分析:从数据总线的位数可以看出,我们用的是32位的(物理)内存。

12610-5i43mop64dr.png

原理图中画出4片内存芯片的一一页,可以看出: X210开发板共使用了4片内存( 每片1Gb=128MB,共512MB) ,每片内存的数据总线都是16位的( 单芯片是16位内存)

如何使用16位内存得到32位内存呢?可以使用并联的方式。在原理图上横向的两颗内存芯片就是并联的。两个芯片加起来成了一个芯片,两个共同组成了三十二位。

并联时,地址总线接法一致,但是数据总线要加起来,这样链接相当于在逻辑上可以把这2颗芯片看成是一个(这一个芯片是32位的,接在xm1端口上)

读数据手册

71502-28t3rsrgh56.png

看数据手册:NT5TU64M16GG-DDR2-1G-G-R18-Consumer.pdf

第十页Block Diagram

这个框图是64Mb*16结构的,指的是8bank,每bank128mBit。

94011-uta9akxabum.png

上图和下图对应
42675-e7kqaflykj.png

210的DDR端口信号中有BA0~BA2,接在内存芯片的BAO~ -BA2上,这些引脚就是用来选择bank的。3个引线就是2三次方,有八个组合。

128Mb通过横向和纵向寻址

65171-dyn71klkfd.png

通过旁边划线的数字来区分多少位

每个bank内部有128Mb,通过row address (14位) + column address (10位)的方式来综合寻址。
一共能寻址的范围是: 2的14次方+2的10次方= 2的24次方。对应16MB (128Mbit) 内存。

初始化流程

相比之前的代码,我们变化的是start.S(小部分变动) link.lds(小部分) sdram_init.S s5pv210.h

链接脚本

SECTIONS
{
    . = 0x20000000;
    
    .text : {
        start.o
        sdram_init.o
        * (.text)
    }
            
    .data : {
        * (.data)
    }
    
    bss_start = .; 
    .bss : {
        * (.bss)
    }
    
    bss_end  = .;    
}

= 0x200000 ,SDRAM的位置

start.S

// 第4步:初始化ddr
bl sdram_asm_init

加了一个函数(sdram_asm_init),在sdram_init.S文件中定义

强调,汇编实现的函数在返回时需要明确使用 返回指令

mov pc, lr

sdram_init.S文件中.global sdram_asm_init,是定义全局使用

27步初始化DD2

(1)首先,DDR初始化和SoC(准确说是和SoC中的DDR控制器)有关,也和开发板使用的DDR芯片有关,和开发板设计时DDR的连接方式也有关。
(2) S5PV210的DDR初始化步骤在SoC数据手册: 1.2.1.3 DDR2这个章节。可知初始化DDR共需27个步骤。
(3)之前分析过X210的内存连接方式是:在DRAM0. 上连接256MB,在DRAM1. 上连接了256MB。所以初始化DRAM时分为2部分,第- - 部分初始化DRAMO,第二部分初始化DRAM1.
(4)我们的代码不是自己写的,这个代码来自于:

第一,九鼎官方的uboot中;

第二,参考了九鼎的裸机教程中对DDR的初始化;

第三,有些参数是我根据自己理解修改过的。

设置IO端口驱动强度

下面的代码不重要,可有可无

ldr    r0, =0xf1e00000
ldr    r1, =0x0
str    r1, [r0, #0x0]

基地址加偏移地址寻址

ldr    r0, =ELFIN_GPIO_BASE

ldr    r1, =0x0000AAAA
str    r1, [r0, #MP1_0DRV_SR_OFFSET]        // 寄存器中对应0b10,就是2X

s5pv210.h 定义了所有相关寄存器地址信息。

...
/*
 * GPIO
 */
#define ELFIN_GPIO_BASE            0xE0200000


#define GPA0CON_OFFSET             0x000
#define GPA0DAT_OFFSET             0x004
#define GPA0PUD_OFFSET             0x008
#define GPA0DRV_SR_OFFSET         0x00C
#define GPA0CONPDN_OFFSET         0x010
#define GPA0PUDPDN_OFFSET         0x014
...
#define MP1_0DRV_SR_OFFSET         0x3CC

我们可通过0xE020_03CC这个地址查找一下手册的描述(P200)

2.2.32 PORT GROUP MP1_0 CONTROL REGISTER
There are six control registers, namely, MP1_0CON, MP1_0DAT, MP1_0PUD, MP1_0DRV, MP1_0CONPDN and
MP1_0PUDPDN in the Port Group MP1_0 Control Registers.

• MP1_0CON, R/W, Address = 0xE020_03C0
• MP1_0DAT, R/W, Address = 0xE020_03C4
• MP1_0PUD, R/W, Address = 0xE020_03C8
• MP1_0DRV, R/W, Address = 0xE020_03CC
• MP1_0CONPDN, R/W, Address = 0xE020_03D0
• MP1_0PUDPDN, R/W, Address = 0xE020_03D4

驱动强度
78988-6xn60bffk1j.png

参考代码里面这里的信息是2X(寄存器中对应2X)

[2n+1:2n] 00 = 1x
n=0~7

等于7的时候是2*7+1所以是bit15~bit0

因为DDR芯片和s5PV210之间是通过很多总线连接的,总线的物理表现就是很多个引脚,也就是说DDR芯片和s5PV210芯片是通过一 些引脚连接的。DDR芯片工作时需要一 定的驱动信号,这个驱动信号需要一定的电平水平才能抗干扰,所以需要设置这些引脚的驱动能力,使DDR正常工作。
DRAM控制器对应的引脚设置为驱动强度2X (我也不知道为什么是2x,什么时候设置成3X、4X?,这东西只能问DDR芯片厂商或者SoC厂商,我们一般参考原厂给的代码)

DRAM port时钟设置

如何设置可以看手册p598

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.

设置

通过上面得知需要设置PhyControl0,手册找到相关描述(P626)

设置PhyControl0.ctrl_start_point 和 PhyControl0.ctrl_inc各为0x10。

/* 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]

210有一个引脚是有时钟的,210给的时钟不够,所以内存芯片内存倍频成高级时钟

以下代码是设置时钟的,主要是开启DLL (dram pll)然后等待锁存。

    /* 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]

时钟设置在我们27步骤的2~4步

测试时钟

该代码可以直接删掉

#if 0    /* Memory margin test 10.01.05 */
    orr    r1, r2, #0x1                @DLL off
    str    r1, [r0, #DMC_PHYCONTROL0]
#endif

设置DDR2

/* setting DDR2 */
ldr    r1, =0x0FFF2010                @ConControl auto refresh off
str    r1, [r0, #DMC_CONCONTROL]

为什么是0x0FFF2010,不知道,参考原厂代码就行。

MEMCONTROL

以下两组地址都是对的:

#define DMC0_MEMCONTROL        0x00202400     // MemControl    BL=4, 1Chip, DDR2 Type, dynamic self refresh, force precharge, dynamic power down off
#define DMC0_MEMCONTROL        0x00212400     // MemControl    BL=4, 1Chip, DDR2 Type, dynamic self refresh, force precharge, dynamic power down off
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]
#define DMC_MEMCONTROL             0x04

22938-en8klvijw2m.png

0x00202400

2就是【22:20】bl里面的2
num_chip 按理说应该是两片,但是官方代码一会一片一会两片

重点需要了解的:

DM0和1是完全对应的


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]
#define DMC_CONCONTROL             0x00
#define DMC_MEMCONTROL             0x04
#define DMC_MEMCONFIG0             0x08
#define DMC_MEMCONFIG1             0x0C
#define DMC0_MEMCONFIG_0    0x20F01323    // MemConfig0    256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_1    0x30F00312    // MemConfig1        默认值
#define DMC0_MEMCONFIG_0    0x20E01323    // MemConfig0    512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_1    0x40F01323    // MemConfig1

手册

1.4.1.3 Memory Chip0 Configuration Register (MemConfig0, R/W, Address=0xF000_0008, 0xF140_0008)
42032-xk4ntsthv5b.png

AXI Base Address
AXI base address [31:24] = chip_base
For example, if chip_base = 0x20, then AXI base address of
memory chip0 becomes 0x2000_0000.

是设置内存的起始地址的

chip_mask

chip_mask是设置掩码的,设置内存多长

AXI Base Address Mask
Upper address bit mask to determine AXI offset address of
memory chip0.
0 = Corresponding address bit is not to be used for comparison
1 = Corresponding address bit is to be used for comparison
For example, if chip_mask = 0xF8, then AXI offset address
becomes 0x0000_0000 ~ 0x07FF_FFFF. If AXI base address
of memory chip0 is 0x2000_0000, then memory chip0 has an
address range of 0x2000_0000 ~ 0x27FF_FFFF.

我们的长度是256M,设置的时候看内存到底有多少

chip_map

地址映射法则

Address Mapping Method (AXI to Memory)
0x0 = Linear ({bank, row, column, width}),
0x1 = Interleaved ({row, bank, column, width}),
0x2 = Mixed1 (
if bank(MSB) = 1’b1,
{1’b1, bank(except MSB), row, column, width}
else
{1’b0, row, bank(except MSB), column, width}),
0x3 ~ 0xf = Reserved

chip_col/chip_row

列地址/行地址

Number of Column Address Bits
0x0 = Reserved
0x1 = 8 bits
0x2 = 9 bits
0x3 = 10 bits
0x4 = 11 bits
0x5 ~ 0xf = Reserved

Number of Row Address Bits
0x0 = 12 bits
0x1 = 13 bits
0x2 = 14 bits
0x3 = 15 bits
0x4 ~ 0xf = Reserved

所以设置为10和14,设置为3和2

chip_bank

内存使用了多少bank

Number of Banks
0x0 = 1 bank
0x1 = 2 banks
0x2 = 4 banks
0x3 = 8 banks
0x4 ~ 0xf = Reserved

从接线可以看出,因为我们接的是:

Xm1_BA0

Xm1_BA1

Xm1_CS1/BA2

三根线,所以2的三次方是8,所以是8bit

笔记

DMCO MEMCONTROL

burst length=4, 1chip,
对应值是0x00202400

DMCO_ MEMCONFIG 0

DRAM0通道中memory chip0的参 数设置寄存器

DMCO MEMCONFIG_ 1

DRAM0通道中memory chip1的参数设置寄存器

总结:

(推论):

三星设置DRAM0通道,允许我们接2片256MB的内存,分别叫memory chip0和memory chipl, 分别用这两个寄存器来设置它的参数。按照三星的设计,chip0的地址应该是0x20000000到0x2FFFFFFF,然后chip1的地址应该是0x30000000~0x3FFFFFFF.各自256MB.
但是我们X210开发板实际在DRAM0端口只接了256MB的内存,所以只用了chip0,没有使用chip1. (我们虽然是2片芯片,然后这两片是并联形成32位内存的,逻辑上只能算1片)。按照这个推论,DMCO_ MEMCONFIG_ 0有用,而DMC0_ MEMCONFIG_ 1无用,所以我直接给他了默认值。

刷新时序

(P632)

1.4.1.10 AC Timing Register for Auto Refresh of memory (TimingAref, R/W, Address = 0xF000_0030,
0xF140_0030)

84400-sektru2v5u.png

Average Periodic Refresh Interval
Should be minimum memory tREFI (all bank) < t_refi * T(mclk),
For example, for the all bank refresh period of 7.8us, and an
mclk frequency of 133MHz, the following value should be
programmed :
7.8 us * 133 MHz = 1038

7.8us * 200MHz

我们这里的是200MHz,所以需要改

所以代码是618

#define DMC0_TIMINGA_REF    0x00000618    // TimingAref    7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)

为什么是200MHz需要了解时钟的概念

其他时序相关

可以不用去了解

#define DMC0_TIMING_ROW 0x28233287 // TimingRow for @200MHz
#define DMC0_TIMING_DATA 0x23240304 // TimingData CL=3
#define DMC0_TIMING_PWR 0x09C80232 // TimingPower

DMC_DIRECTCMD

这个寄存器是个命令寄存器,我们210通过向这个寄存器写值来向DDR芯片发送命令(通过命令总线),这些命令
应该都是用来配置DDR芯片工作参数。

手册(P624)

1.4.1.5 Memory Direct Command Register (DirectCmd, R/W, Address = 0xF000_0010, 0xF140_0010)

Type of Direct Command
0x0 = MRS/EMRS (mode register setting),
0x1 = PALL (all banks precharge),
0x2 = PRE (per bank precharge),
0x3 = DPD (deep power down),
0x4 = REFS (self refresh),
0x5 = REFA (auto refresh),
0x6 = CKEL (active/ precharge power down),
0x7 = NOP (exit from active/ precharge power down or deep
power down,
0x8 = REFSX (exit from self refresh)
0x9 = MRR (mode register reading),
0xa ~ 0xf = Reserved
If a direct command is issued, AXI masters must not access
memory. It is strongly recommended to check the command
queue’s state by Concontrol.chip0/1_empty before issuing a
direct command
You must disable dynamic power down, dynamic self refresh
and force precharge function (MemControl register).
MRS/EMRS and MRR commands should be issued if all banks
are in idle state.
If MRS/EMRS and MRR is issued to LPDDR2, the CA pins
must be mapped as follows.
MA[7:0] = {cmd_addr[1:0], cmd_bank[2:0], cmd_addr[12:10]},
OP[7:0] = cmd_addr[9:2]

27858-rjrdab3vz9m.png

根据十七步骤的方法,发送的命令需要顺序:


    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, =0x00110440                @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, =DMC1_MEMCONTROL            @MemControl    BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
    str    r1, [r0, #DMC_MEMCONTROL]

总结

DDR配置过程比较复杂,基本上是按照DDR控制器的时序要求来做的,其中很多参数要结合DDR芯片本身的参数来定,还有些参数是时序参数,要去详细计算。所以DDR配置非常繁琐、细致、专业。所以我们对DDR初始化的态度就是:学会这种思路和方法,结合文档和代码能看懂,会算一些 常见的参数即可。

重定位代码到SDRAM中

DRAM初始化之后,实际上重定位代码过程和之前重定位到SRAM中完全相同。

完整代码

对于当前代码,0的代码是没问题的,但是1出现了问题

所以正常使用的时候需要将初始化1的代码删掉

s5pv210.h


/* S5PC110 device base addresses */
#define ELFIN_DMA_BASE            0xE0900000
#define ELFIN_LCD_BASE            0xF8000000
#define ELFIN_USB_HOST_BASE        0xEC200000
#define ELFIN_I2C_BASE            0xE1800000
#define ELFIN_I2S_BASE            0xE2100000
#define ELFIN_ADC_BASE            0xE1700000
#define ELFIN_SPI_BASE            0xE1300000


#define ELFIN_HSMMC_0_BASE        0xEB000000
#define ELFIN_HSMMC_1_BASE        0xEB100000
#define ELFIN_HSMMC_2_BASE        0xEB200000
#define ELFIN_HSMMC_3_BASE        0xEB300000

#define ELFIN_CLOCK_POWER_BASE        0xE0100000

#define IO_RET_REL            ((1 << 31) | (1 << 29) | (1 << 28))

/* Clock & Power Controller for s5pc110*/
#define APLL_LOCK_OFFSET        0x00
#define MPLL_LOCK_OFFSET        0x08
#define EPLL_LOCK_OFFSET        0x10
#define VPLL_LOCK_OFFSET        0x20
#define APLL_CON0_OFFSET        0x100
#define APLL_CON1_OFFSET        0x104
#define MPLL_CON_OFFSET            0x108
#define EPLL_CON_OFFSET            0x110
#define VPLL_CON_OFFSET            0x120

#define CLK_SRC0_OFFSET            0x200
#define CLK_SRC1_OFFSET            0x204
#define CLK_SRC2_OFFSET            0x208
#define CLK_SRC3_OFFSET            0x20c
#define CLK_SRC4_OFFSET            0x210
#define CLK_SRC5_OFFSET            0x214
#define CLK_SRC6_OFFSET            0x218
#define CLK_SRC_MASK0_OFFSET        0x280
#define CLK_SRC_MASK1_OFFSET        0x284

#define CLK_DIV0_OFFSET            0x300
#define CLK_DIV1_OFFSET            0x304
#define CLK_DIV2_OFFSET            0x308
#define CLK_DIV3_OFFSET            0x30c
#define CLK_DIV4_OFFSET            0x310
#define CLK_DIV5_OFFSET            0x314
#define CLK_DIV6_OFFSET            0x318
#define CLK_DIV7_OFFSET            0x31c

#define CLK_GATE_IP0_OFFSET        0x460
#define CLK_GATE_IP1_OFFSET        0x464
#define CLK_GATE_IP2_OFFSET        0x468
#define CLK_GATE_IP3_OFFSET        0x46c
#define CLK_GATE_IP4_OFFSET        0x470
#define CLK_GATE_BLOCK_OFFSET        0x480

#define CLK_OUT_OFFSET            0x500
#define CLK_DIV_STAT0_OFFSET        0x1000
#define CLK_DIV_STAT1_OFFSET        0x1004
#define CLK_MUX_STAT0_OFFSET        0x1100
#define CLK_MUX_STAT1_OFFSET        0x1104
#define SW_RST_OFFSET            0x2000

#define ONEDRAM_CFG_OFFSET        0x6208

#define OSC_CON_OFFSET            0x8000
#define RST_STAT_OFFSET            0xa000
#define PWR_CFG_OFFSET            0xc000
#define    EINT_WAKEUP_MASK_OFFSET        0xc004
#define WAKEUP_MASK_OFFSET        0xc008
#define NORMAL_CFG_OFFSET        0xc010
#define IDLE_CFG_OFFSET            0xc020
#define STOP_CFG_OFFSET            0xc030
#define STOP_MEM_CFG_OFFSET        0xc034
#define SLEEP_CFG_OFFSET        0xc040
#define OSC_FREQ_OFFSET            0xc100
#define OSC_STABLE_OFFSET        0xc104
#define PWR_STABLE_OFFSET        0xc108
#define MTC_STABLE_OFFSET        0xc110
#define CLAMP_STABLE_OFFSET        0xc114
#define WAKEUP_STAT_OFFSET        0xc200
#define BLK_PWR_STAT_OFFSET        0xc204
#define BODY_BIAS_CON_OFFSET        0xc300
#define ION_SKEW_CON_OFFSET        0xc310
#define ION_SKEW_MON_OFFSET        0xc314
#define IOFF_SKEW_CON_OFFSET        0xc320
#define IOFF_SKEW_MON_OFFSET        0xc324
#define OTHERS_OFFSET            0xe000
#define OM_STAT_OFFSET            0xe100
#define MIE_CONTROL_OFFSET        0xe800
#define HDMI_CONTROL_OFFSET        0xe804
#define USB_PHY_CONTROL_OFFSET        0xe80c
#define DAC_CONTROL_OFFSET        0xe810
#define MIPI_DPHY_CONTROL_OFFSET    0xe814
#define ADC_CONTROL_OFFSET        0xe818
#define PS_HOLD_CONTROL_OFFSET        0xe81c

#define INFORM0_OFFSET            0xf000
#define INFORM1_OFFSET            0xf004
#define INFORM2_OFFSET            0xf008
#define INFORM3_OFFSET            0xf00c
#define INFORM4_OFFSET            0xf010
#define INFORM5_OFFSET            0xf014
#define INFORM6_OFFSET            0xf018
#define INFORM7_OFFSET            0xf01c

#define INF_REG0_OFFSET            0x00
#define INF_REG1_OFFSET            0x04
#define INF_REG2_OFFSET            0x08
#define INF_REG3_OFFSET            0x0c
#define INF_REG4_OFFSET            0x10
#define INF_REG5_OFFSET            0x14
#define INF_REG6_OFFSET            0x18
#define INF_REG7_OFFSET            0x1c


/*
 * GPIO
 */
#define ELFIN_GPIO_BASE            0xE0200000


#define GPA0CON_OFFSET             0x000
#define GPA0DAT_OFFSET             0x004
#define GPA0PUD_OFFSET             0x008
#define GPA0DRV_SR_OFFSET         0x00C
#define GPA0CONPDN_OFFSET         0x010
#define GPA0PUDPDN_OFFSET         0x014

#define GPA1CON_OFFSET             0x020
#define GPA1DAT_OFFSET             0x024
#define GPA1PUD_OFFSET             0x028
#define GPA1DRV_SR_OFFSET         0x02C
#define GPA1CONPDN_OFFSET         0x030
#define GPA1PUDPDN_OFFSET         0x034

#define GPBCON_OFFSET             0x040
#define GPBDAT_OFFSET             0x044
#define GPBPUD_OFFSET             0x048
#define GPBDRV_SR_OFFSET         0x04C
#define GPBCONPDN_OFFSET         0x050
#define GPBPUDPDN_OFFSET         0x054

#define GPC0CON_OFFSET             0x060
#define GPC0DAT_OFFSET             0x064
#define GPC0PUD_OFFSET             0x068
#define GPC0DRV_SR_OFFSET         0x06C
#define GPC0CONPDN_OFFSET         0x070
#define GPC0PUDPDN_OFFSET         0x074

#define GPC1CON_OFFSET             0x080
#define GPC1DAT_OFFSET             0x084
#define GPC1PUD_OFFSET             0x088
#define GPC1DRV_SR_OFFSET         0x08C
#define GPC1CONPDN_OFFSET         0x090
#define GPC1PUDPDN_OFFSET         0x094

#define GPD0CON_OFFSET             0x0A0
#define GPD0DAT_OFFSET             0x0A4
#define GPD0PUD_OFFSET             0x0A8
#define GPD0DRV_SR_OFFSET         0x0AC
#define GPD0CONPDN_OFFSET         0x0B0
#define GPD0PUDPDN_OFFSET         0x0B4

#define GPD1CON_OFFSET             0x0C0
#define GPD1DAT_OFFSET             0x0C4
#define GPD1PUD_OFFSET             0x0C8
#define GPD1DRV_SR_OFFSET         0x0CC
#define GPD1CONPDN_OFFSET         0x0D0
#define GPD1PUDPDN_OFFSET         0x0D4

#define GPE0CON_OFFSET             0x0E0
#define GPE0DAT_OFFSET             0x0E4
#define GPE0PUD_OFFSET             0x0E8
#define GPE0DRV_SR_OFFSET         0x0EC
#define GPE0CONPDN_OFFSET         0x0F0
#define GPE0PUDPDN_OFFSET         0x0F4

#define GPE1CON_OFFSET             0x100
#define GPE1DAT_OFFSET             0x104
#define GPE1PUD_OFFSET             0x108
#define GPE1DRV_SR_OFFSET         0x10C
#define GPE1CONPDN_OFFSET         0x110
#define GPE1PUDPDN_OFFSET         0x114

#define GPF0CON_OFFSET             0x120
#define GPF0DAT_OFFSET             0x124
#define GPF0PUD_OFFSET             0x128
#define GPF0DRV_SR_OFFSET         0x12C
#define GPF0CONPDN_OFFSET         0x130
#define GPF0PUDPDN_OFFSET         0x134

#define GPF1CON_OFFSET             0x140
#define GPF1DAT_OFFSET             0x144
#define GPF1PUD_OFFSET             0x148
#define GPF1DRV_SR_OFFSET         0x14C
#define GPF1CONPDN_OFFSET         0x150
#define GPF1PUDPDN_OFFSET         0x154

#define GPF2CON_OFFSET             0x160
#define GPF2DAT_OFFSET             0x164
#define GPF2PUD_OFFSET             0x168
#define GPF2DRV_SR_OFFSET         0x16C
#define GPF2CONPDN_OFFSET         0x170
#define GPF2PUDPDN_OFFSET         0x174

#define GPF3CON_OFFSET             0x180
#define GPF3DAT_OFFSET             0x184
#define GPF3PUD_OFFSET             0x188
#define GPF3DRV_SR_OFFSET         0x18C
#define GPF3CONPDN_OFFSET         0x190
#define GPF3PUDPDN_OFFSET         0x194

#define GPG0CON_OFFSET             0x1A0
#define GPG0DAT_OFFSET             0x1A4
#define GPG0PUD_OFFSET             0x1A8
#define GPG0DRV_SR_OFFSET         0x1AC
#define GPG0CONPDN_OFFSET         0x1B0
#define GPG0PUDPDN_OFFSET         0x1B4

#define GPG1CON_OFFSET             0x1C0
#define GPG1DAT_OFFSET             0x1C4
#define GPG1PUD_OFFSET             0x1C8
#define GPG1DRV_SR_OFFSET         0x1CC
#define GPG1CONPDN_OFFSET         0x1D0
#define GPG1PUDPDN_OFFSET         0x1D4

#define GPG2CON_OFFSET             0x1E0
#define GPG2DAT_OFFSET             0x1E4
#define GPG2PUD_OFFSET             0x1E8
#define GPG2DRV_SR_OFFSET         0x1EC
#define GPG2CONPDN_OFFSET         0x1F0
#define GPG2PUDPDN_OFFSET         0x1F4

#define GPG3CON_OFFSET             0x200
#define GPG3DAT_OFFSET             0x204
#define GPG3PUD_OFFSET             0x208
#define GPG3DRV_SR_OFFSET         0x20C
#define GPG3CONPDN_OFFSET         0x210
#define GPG3PUDPDN_OFFSET         0x214

#define MP1_0DRV_SR_OFFSET         0x3CC
#define MP1_1DRV_SR_OFFSET         0x3EC
#define MP1_2DRV_SR_OFFSET         0x40C
#define MP1_3DRV_SR_OFFSET         0x42C
#define MP1_4DRV_SR_OFFSET         0x44C
#define MP1_5DRV_SR_OFFSET         0x46C
#define MP1_6DRV_SR_OFFSET         0x48C
#define MP1_7DRV_SR_OFFSET         0x4AC
#define MP1_8DRV_SR_OFFSET         0x4CC

#define MP2_0DRV_SR_OFFSET         0x4EC
#define MP2_1DRV_SR_OFFSET         0x50C
#define MP2_2DRV_SR_OFFSET         0x52C
#define MP2_3DRV_SR_OFFSET         0x54C
#define MP2_4DRV_SR_OFFSET         0x56C
#define MP2_5DRV_SR_OFFSET         0x58C
#define MP2_6DRV_SR_OFFSET         0x5AC
#define MP2_7DRV_SR_OFFSET         0x5CC
#define MP2_8DRV_SR_OFFSET         0x5EC

/* GPH0 */
#define GPH0CON_OFFSET            0xc00
#define GPH0DAT_OFFSET            0xc04
#define GPH0PUD_OFFSET            0xc08
#define GPH0DRV_OFFSET            0xc0c

/* GPH1 */
#define GPH1CON_OFFSET            0xc20
#define GPH1DAT_OFFSET            0xc24
#define GPH1PUD_OFFSET            0xc28
#define GPH1DRV_OFFSET            0xc2c

/* GPH2 */
#define GPH2CON_OFFSET            0xc40
#define GPH2DAT_OFFSET            0xc44
#define GPH2PUD_OFFSET            0xc48
#define GPH2DRV_OFFSET            0xc4c

/* GPH3 */
#define GPH3CON_OFFSET            0xc60
#define GPH3DAT_OFFSET            0xc64
#define GPH3PUD_OFFSET            0xc68
#define GPH3DRV_OFFSET            0xc6c


#define GPICON_OFFSET             0x220
#define GPIPUD_OFFSET             0x228
#define GPIDRV_OFFSET_SR         0x22C
#define GPIPUDPDN_OFFSET         0x234

#define GPJ0CON_OFFSET             0x240
#define GPJ0DAT_OFFSET             0x244
#define GPJ0PUD_OFFSET             0x248
#define GPJ0DRV_SR_OFFSET         0x24C
#define GPJ0CONPDN_OFFSET         0x250
#define GPJ0PUDPDN_OFFSET         0x254

#define GPJ1CON_OFFSET             0x260
#define GPJ1DAT_OFFSET             0x264
#define GPJ1PUD_OFFSET             0x268
#define GPJ1DRV_SR_OFFSET         0x26C
#define GPJ1CONPDN_OFFSET         0x270
#define GPJ1PUDPDN_OFFSET         0x274

#define GPJ2CON_OFFSET             0x280
#define GPJ2DAT_OFFSET             0x284
#define GPJ2PUD_OFFSET             0x288
#define GPJ2DRV_SR_OFFSET         0x28C
#define GPJ2CONPDN_OFFSET         0x290
#define GPJ2PUDPDN_OFFSET         0x294

#define GPJ3CON_OFFSET             0x2A0
#define GPJ3DAT_OFFSET             0x2A4
#define GPJ3PUD_OFFSET             0x2A8
#define GPJ3DRV_SR_OFFSET         0x2AC
#define GPJ3CONPDN_OFFSET         0x2B0
#define GPJ3PUDPDN_OFFSET         0x2B4

#define GPJ4CON_OFFSET             0x2C0
#define GPJ4DAT_OFFSET             0x2C4
#define GPJ4PUD_OFFSET             0x2C8
#define GPJ4DRV_SR_OFFSET         0x2CC
#define GPJ4CONPDN_OFFSET         0x2D0
#define GPJ4PUDPDN_OFFSET         0x2D4


/*
 * Interrupt
 */
#define ELFIN_VIC0_BASE_ADDR        (0xF2000000)
#define ELFIN_VIC1_BASE_ADDR        (0xF2100000)
#define ELFIN_VIC2_BASE_ADDR        (0xF2200000)

#define ELFIN_TZIC0_BASE_ADDR        (0xF2800000)
#define ELFIN_TZIC1_BASE_ADDR        (0xF2900000)
#define ELFIN_TZIC2_BASE_ADDR        (0xF2A00000)

#define oINTMOD                (0x0C)        // VIC INT SELECT (IRQ or FIQ)
#define oINTUNMSK            (0x10)        // VIC INT EN (Unmask by writing 1)
#define oINTMSK                (0x14)        // VIC INT EN CLEAR (Mask by writing 1)
#define oINTSUBMSK            (0x1C)        // VIC SOFT INT CLEAR
#define oVECTADDR            (0xF00)        // VIC ADDRESS

/*
 * Watchdog timer
 */
#define ELFIN_WATCHDOG_BASE        0xE2700000

#define WTCON_OFFSET            0x00
#define WTDAT_OFFSET            0x08
#define WTCNT_OFFSET            0x0C

#define WTCON_REG            __REG(ELFIN_WATCHDOG_BASE+WTCON_OFFSET)
#define WTDAT_REG            __REG(ELFIN_WATCHDOG_BASE+WTDAT_OFFSET)
#define WTCNT_REG            __REG(ELFIN_WATCHDOG_BASE+WTCNT_OFFSET)

/*
 * UART
 */
#define ELFIN_UART_BASE            0XE2900000

#define ELFIN_UART0_OFFSET        0x0000
#define ELFIN_UART1_OFFSET        0x0400
#define ELFIN_UART2_OFFSET        0x0800
#define ELFIN_UART3_OFFSET        0x0c00

#if defined(CONFIG_SERIAL0)
#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET)
#elif defined(CONFIG_SERIAL1)
#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET)
#elif defined(CONFIG_SERIAL2)
#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART2_OFFSET)
#elif defined(CONFIG_SERIAL3)
#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART3_OFFSET)
#else
#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET)
#endif

#define ULCON_OFFSET            0x00
#define UCON_OFFSET            0x04
#define UFCON_OFFSET            0x08
#define UMCON_OFFSET            0x0C
#define UTRSTAT_OFFSET            0x10
#define UERSTAT_OFFSET            0x14
#define UFSTAT_OFFSET            0x18
#define UMSTAT_OFFSET            0x1C
#define UTXH_OFFSET            0x20
#define URXH_OFFSET            0x24
#define UBRDIV_OFFSET            0x28
#define UDIVSLOT_OFFSET            0x2C
#define UINTP_OFFSET            0x30
#define UINTSP_OFFSET            0x34
#define UINTM_OFFSET            0x38

#define UTRSTAT_TX_EMPTY        BIT2
#define UTRSTAT_RX_READY        BIT0
#define UART_ERR_MASK            0xF


/*
 * PWM timer
 */
#define ELFIN_TIMER_BASE        0xE2500000

#define TCFG0_REG            __REG(0xE2500000)
#define TCFG1_REG            __REG(0xE2500004)
#define TCON_REG            __REG(0xE2500008)
#define TCNTB0_REG            __REG(0xE250000c)
#define TCMPB0_REG            __REG(0xE2500010)
#define TCNTO0_REG            __REG(0xE2500014)
#define TCNTB1_REG            __REG(0xE2500018)
#define TCMPB1_REG            __REG(0xE250001c)
#define TCNTO1_REG            __REG(0xE2500020)
#define TCNTB2_REG            __REG(0xE2500024)
#define TCMPB2_REG            __REG(0xE2500028)
#define TCNTO2_REG            __REG(0xE250002c)
#define TCNTB3_REG            __REG(0xE2500030)
#define TCMPB3_REG            __REG(0xE2500034)
#define TCNTO3_REG            __REG(0xE2500038)
#define TCNTB4_REG            __REG(0xE250003c)
#define TCNTO4_REG            __REG(0xE2500040)
#define TINT_CSTAT            __REG(0xE2500044)

/* Fields */
#define fTCFG0_DZONE            Fld(8,16)       /* the dead zone length (= timer 0) */
#define fTCFG0_PRE1            Fld(8,8)        /* prescaler value for time 2,3,4 */
#define fTCFG0_PRE0            Fld(8,0)        /* prescaler value for time 0,1 */
#define fTCFG1_MUX4            Fld(4,16)
/* bits */
#define TCFG0_DZONE(x)            FInsrt((x), fTCFG0_DZONE)
#define TCFG0_PRE1(x)            FInsrt((x), fTCFG0_PRE1)
#define TCFG0_PRE0(x)            FInsrt((x), fTCFG0_PRE0)
#define TCON_4_AUTO            (1 << 22)       /* auto reload on/off for Timer 4 */
#define TCON_4_UPDATE            (1 << 21)       /* manual Update TCNTB4 */
#define TCON_4_ONOFF            (1 << 20)       /* 0: Stop, 1: start Timer 4 */
#define COUNT_4_ON            (TCON_4_ONOFF*1)
#define COUNT_4_OFF            (TCON_4_ONOFF*0)
#define TCON_3_AUTO            (1 << 19)       /* auto reload on/off for Timer 3 */
#define TIMER3_ATLOAD_ON        (TCON_3_AUTO*1)
#define TIMER3_ATLAOD_OFF        FClrBit(TCON, TCON_3_AUTO)
#define TCON_3_INVERT            (1 << 18)       /* 1: Inverter on for TOUT3 */
#define TIMER3_IVT_ON            (TCON_3_INVERT*1)
#define TIMER3_IVT_OFF            (FClrBit(TCON, TCON_3_INVERT))
#define TCON_3_MAN            (1 << 17)       /* manual Update TCNTB3,TCMPB3 */
#define TIMER3_MANUP            (TCON_3_MAN*1)
#define TIMER3_NOP            (FClrBit(TCON, TCON_3_MAN))
#define TCON_3_ONOFF            (1 << 16)       /* 0: Stop, 1: start Timer 3 */
#define TIMER3_ON            (TCON_3_ONOFF*1)
#define TIMER3_OFF            (FClrBit(TCON, TCON_3_ONOFF))
/* macros */
#define GET_PRESCALE_TIMER4(x)        FExtr((x), fTCFG0_PRE1)
#define GET_DIVIDER_TIMER4(x)        FExtr((x), fTCFG1_MUX4)


#define MP01CON_OFFSET             0x2E0
#define MP01DAT_OFFSET             0x2E4
#define MP01PUD_OFFSET             0x2E8
#define MP01DRV_SR_OFFSET         0x2EC
#define MP01CONPDN_OFFSET         0x2E0
#define MP01PUDPDN_OFFSET         0x2E4

#define MP02CON_OFFSET                  0x300
#define MP02DAT_OFFSET                  0x304
#define MP02PUD_OFFSET                  0x308
#define MP02DRV_SR_OFFSET               0x30c
#define MP02CONPDN_OFFSET               0x310
#define MP02PUDPDN_OFFSET               0x314

#define MP03CON_OFFSET                  0x320
#define MP03DAT_OFFSET                  0x324
#define MP03PUD_OFFSET                  0x328
#define MP03DRV_SR_OFFSET               0x32c
#define MP03CONPDN_OFFSET               0x330
#define MP03PUDPDN_OFFSET               0x334

#define MP06CON_OFFSET                  0x380
#define MP06DAT_OFFSET                  0x384
#define MP06PUD_OFFSET                  0x388
#define MP06DRV_SR_OFFSET               0x38C
#define MP06CONPDN_OFFSET               0x390
#define MP06PUDPDN_OFFSET               0x394

#define MP07CON_OFFSET                  0x3A0
#define MP07DAT_OFFSET                  0x3A4
#define MP07PUD_OFFSET                  0x3A8
#define MP07DRV_SR_OFFSET               0x3AC
#define MP07CONPDN_OFFSET               0x3B0
#define MP07PUDPDN_OFFSET               0x3B4


/*
 * Nand flash controller
 */
#define ELFIN_NAND_BASE            0xB0E00000
#define ELFIN_NAND_ECC_BASE        0xB0E20000

#define NFCONF_OFFSET               0x00
#define NFCONT_OFFSET               0x04
#define NFCMMD_OFFSET               0x08
#define NFADDR_OFFSET               0x0c
#define NFDATA_OFFSET            0x10
#define NFMECCDATA0_OFFSET          0x14
#define NFMECCDATA1_OFFSET          0x18
#define NFSECCDATA0_OFFSET          0x1c
#define NFSBLK_OFFSET               0x20
#define NFEBLK_OFFSET               0x24
#define NFSTAT_OFFSET               0x28
#define NFESTAT0_OFFSET             0x2c
#define NFESTAT1_OFFSET             0x30
#define NFMECC0_OFFSET              0x34
#define NFMECC1_OFFSET              0x38
#define NFSECC_OFFSET               0x3c
#define NFMLCBITPT_OFFSET           0x40
#define NFECCCONF_OFFSET         0x000 // R/W ECC configuration register 0x0000_0000
#define NFECCCONT_OFFSET         0x020 // R/W ECC control register 0x0000_0000
#define NFECCSTAT_OFFSET         0x030 // R ECC status register 0x0000_0000
#define NFECCSECSTAT_OFFSET         0x040 // R ECC sector status register 0x0000_0000
#define NFECCPRGECC0_OFFSET         0x090 // R ECC parity code0 register for page program 0x0000_0000
#define NFECCPRGECC1_OFFSET         0x094 // R ECC parity code1 register for page program 0x0000_0000
#define NFECCPRGECC2_OFFSET         0x098 // R ECC parity code2 register for page program 0x0000_0000
#define NFECCPRGECC3_OFFSET         0x09C // R ECC parity code3 register for page program 0x0000_0000
#define NFECCPRGECC4_OFFSET         0x0A0 // R ECC parity code4 register for page program 0x0000_0000
#define NFECCPRGECC5_OFFSET         0x0A4 // R ECC parity code5 register for page program 0x0000_0000
#define NFECCPRGECC6_OFFSET         0x0A8 // R ECC parity code6 register for page program 0x0000_0000
#define NFECCERL0_OFFSET        0x0C0 // R ECC error byte location0 register 0x0000_0000
#define NFECCERL1_OFFSET        0x0C4 // R ECC error byte location1 register 0x0000_0000
#define NFECCERL2_OFFSET        0x0C8 // R ECC error byte location2 register 0x0000_0000
#define NFECCERL3_OFFSET         0x0CC // R ECC error byte location3 register 0x0000_0000
#define NFECCERL4_OFFSET         0x0D0 // R ECC error byte location4 register 0x0000_0000
#define NFECCERL5_OFFSET         0x0D4 // R ECC error byte location5 register 0x0000_0000
#define NFECCERL6_OFFSET         0x0D8 // R ECC error byte location6 register 0x0000_0000
#define NFECCERL7_OFFSET         0x0DC // R ECC error byte location7 register 0x0000_0000
#define NFECCERP0_OFFSET         0x0F0 // R ECC error bit pattern0 register 0x0000_0000
#define NFECCERP1_OFFSET         0x0F4 // R ECC error bit pattern1 register 0x0000_0000
#define NFECCERP2_OFFSET         0x0F8 // R ECC error bit pattern2 register 0x0000_0000
#define NFECCERP3_OFFSET         0x0FC // R ECC error bit pattern3 register 0x0000_0000
#define NFECCCONECC0_OFFSET         0x110 // R/W ECC parity conversion code0 register 0x0000_0000
#define NFECCCONECC1_OFFSET         0x114 // R/W ECC parity conversion code1 register 0x0000_0000
#define NFECCCONECC2_OFFSET         0x118 // R/W ECC parity conversion code2 register 0x0000_0000
#define NFECCCONECC3_OFFSET         0x11C // R/W ECC parity conversion code3 register 0x0000_0000
#define NFECCCONECC4_OFFSET         0x120 // R/W ECC parity conversion code4 register 0x0000_0000
#define NFECCCONECC5_OFFSET         0x124 // R/W ECC parity conversion code5 register 0x0000_0000
#define NFECCCONECC6_OFFSET        0x128 // R/W ECC parity conversion code6 register 0x0000_0000

#define NFCONF                (ELFIN_NAND_BASE+NFCONF_OFFSET)
#define NFCONT                (ELFIN_NAND_BASE+NFCONT_OFFSET)
#define NFCMMD                (ELFIN_NAND_BASE+NFCMMD_OFFSET)
#define NFADDR                   (ELFIN_NAND_BASE+NFADDR_OFFSET)
#define NFDATA                  (ELFIN_NAND_BASE+NFDATA_OFFSET)
#define NFMECCDATA0             (ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
#define NFMECCDATA1             (ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
#define NFSECCDATA0              (ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
#define NFSBLK                  (ELFIN_NAND_BASE+NFSBLK_OFFSET)
#define NFEBLK                   (ELFIN_NAND_BASE+NFEBLK_OFFSET)
#define NFSTAT                   (ELFIN_NAND_BASE+NFSTAT_OFFSET)
#define NFESTAT0                 (ELFIN_NAND_BASE+NFESTAT0_OFFSET)
#define NFESTAT1                 (ELFIN_NAND_BASE+NFESTAT1_OFFSET)
#define NFMECC0                  (ELFIN_NAND_BASE+NFMECC0_OFFSET)
#define NFMECC1                  (ELFIN_NAND_BASE+NFMECC1_OFFSET)
#define NFSECC                   (ELFIN_NAND_BASE+NFSECC_OFFSET)
#define NFMLCBITPT                   (ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)

#define NFECCCONF            (ELFIN_NAND_ECC_BASE+NFECCCONF_OFFSET)
#define NFECCCONT            (ELFIN_NAND_ECC_BASE+NFECCCONT_OFFSET)
#define NFECCSTAT            (ELFIN_NAND_ECC_BASE+NFECCSTAT_OFFSET)
#define NFECCSECSTAT            (ELFIN_NAND_ECC_BASE+NFECCSECSTAT_OFFSET)
#define NFECCPRGECC0            (ELFIN_NAND_ECC_BASE+NFECCPRGECC0_OFFSET)
#define NFECCPRGECC1            (ELFIN_NAND_ECC_BASE+NFECCPRGECC1_OFFSET)
#define NFECCPRGECC2            (ELFIN_NAND_ECC_BASE+NFECCPRGECC2_OFFSET)
#define NFECCPRGECC3            (ELFIN_NAND_ECC_BASE+NFECCPRGECC3_OFFSET)
#define NFECCPRGECC4            (ELFIN_NAND_ECC_BASE+NFECCPRGECC4_OFFSET)
#define NFECCPRGECC5            (ELFIN_NAND_ECC_BASE+NFECCPRGECC5_OFFSET)
#define NFECCPRGECC6            (ELFIN_NAND_ECC_BASE+NFECCPRGECC6_OFFSET)
#define NFECCERL0            (ELFIN_NAND_ECC_BASE+NFECCERL0_OFFSET)
#define NFECCERL1            (ELFIN_NAND_ECC_BASE+NFECCERL1_OFFSET)
#define NFECCERL2            (ELFIN_NAND_ECC_BASE+NFECCERL2_OFFSET)
#define NFECCERL3            (ELFIN_NAND_ECC_BASE+NFECCERL3_OFFSET)
#define NFECCERL4            (ELFIN_NAND_ECC_BASE+NFECCERL4_OFFSET)
#define NFECCERL5            (ELFIN_NAND_ECC_BASE+NFECCERL5_OFFSET)
#define NFECCERL6            (ELFIN_NAND_ECC_BASE+NFECCERL6_OFFSET)
#define NFECCERL7            (ELFIN_NAND_ECC_BASE+NFECCERL7_OFFSET)
#define NFECCERP0            (ELFIN_NAND_ECC_BASE+NFECCERP0_OFFSET)
#define NFECCERP1            (ELFIN_NAND_ECC_BASE+NFECCERP1_OFFSET)
#define NFECCERP2            (ELFIN_NAND_ECC_BASE+NFECCERP2_OFFSET)
#define NFECCERP3            (ELFIN_NAND_ECC_BASE+NFECCERP3_OFFSET)
#define NFECCCONECC0            (ELFIN_NAND_ECC_BASE+NFECCCONECC0_OFFSET)
#define NFECCCONECC1            (ELFIN_NAND_ECC_BASE+NFECCCONECC1_OFFSET)
#define NFECCCONECC2            (ELFIN_NAND_ECC_BASE+NFECCCONECC2_OFFSET)
#define NFECCCONECC3            (ELFIN_NAND_ECC_BASE+NFECCCONECC3_OFFSET)
#define NFECCCONECC4            (ELFIN_NAND_ECC_BASE+NFECCCONECC4_OFFSET)
#define NFECCCONECC5            (ELFIN_NAND_ECC_BASE+NFECCCONECC5_OFFSET)
#define NFECCCONECC6            (ELFIN_NAND_ECC_BASE+NFECCCONECC6_OFFSET)


#define NFCONF_REG            __REG(ELFIN_NAND_BASE+NFCONF_OFFSET)
#define NFCONT_REG            __REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
#define NFCMD_REG            __REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
#define NFADDR_REG                   __REG(ELFIN_NAND_BASE+NFADDR_OFFSET)
#define NFDATA_REG                  __REG(ELFIN_NAND_BASE+NFDATA_OFFSET)
#define NFDATA8_REG                  __REGb(ELFIN_NAND_BASE+NFDATA_OFFSET)
#define NFMECCDATA0_REG             __REG(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
#define NFMECCDATA1_REG             __REG(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
#define NFSECCDATA0_REG              __REG(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
#define NFSBLK_REG                  __REG(ELFIN_NAND_BASE+NFSBLK_OFFSET)
#define NFEBLK_REG                   __REG(ELFIN_NAND_BASE+NFEBLK_OFFSET)
#define NFSTAT_REG                   __REG(ELFIN_NAND_BASE+NFSTAT_OFFSET)
#define NFESTAT0_REG                 __REG(ELFIN_NAND_BASE+NFESTAT0_OFFSET)
#define NFESTAT1_REG                 __REG(ELFIN_NAND_BASE+NFESTAT1_OFFSET)
#define NFMECC0_REG                  __REG(ELFIN_NAND_BASE+NFMECC0_OFFSET)
#define NFMECC1_REG                  __REG(ELFIN_NAND_BASE+NFMECC1_OFFSET)
#define NFSECC_REG                   __REG(ELFIN_NAND_BASE+NFSECC_OFFSET)
#define NFMLCBITPT_REG                 __REG(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)

#define NFCONF_ECC_MLC            (1<<24)

#define NFCONF_ECC_1BIT            (0<<23)
#define NFCONF_ECC_4BIT            (2<<23)
#define NFCONF_ECC_8BIT            (1<<23)

#define NFCONT_ECC_ENC            (1<<18)
#define NFCONT_WP            (1<<16)
#define NFCONT_MECCLOCK            (1<<7)
#define NFCONT_SECCLOCK            (1<<6)
#define NFCONT_INITMECC            (1<<5)
#define NFCONT_INITSECC            (1<<4)
#define NFCONT_INITECC            (NFCONT_INITMECC | NFCONT_INITSECC)
#define NFCONT_CS            (1<<1)
#define NFSTAT_ECCENCDONE        (1<<25)
#define NFSTAT_ECCDECDONE        (1<<24)
#define NFSTAT_RnB            (1<<0)
#define NFESTAT0_ECCBUSY        (1<<31)


/* Access Controller (TZPC) */
#define TZPC_DECPROT0SET_OFFSET        0x804
#define TZPC_DECPROT1SET_OFFSET        0x810
#define TZPC_DECPROT2SET_OFFSET        0x81C
#define TZPC_DECPROT3SET_OFFSET        0x828


/*************************************************************
 * OneNAND Controller
 *************************************************************/
#define ELFIN_ONENAND_BASE        0xB0000000
#define ELFIN_ONENANDCON_BASE        (ELFIN_ONENAND_BASE + 0x600000)

#define ONENAND_IF_CTRL_OFFSET            0x100
#define ONENAND_IF_CMD_OFFSET            0x104
#define ONENAND_IF_ASYNC_TIMING_CTRL_OFFSET    0x108
#define ONENAND_IF_STATUS_OFFSET        0x10C
#define DMA_SRC_ADDR_OFFSET            0x400
#define DMA_SRC_CFG_OFFSET            0x404
#define DMA_DST_ADDR_OFFSET            0x408
#define DMA_DST_CFG_OFFSET            0x40C
#define DMA_TRANS_SIZE_OFFSET            0x414
#define DMA_TRANS_CMD_OFFSET            0x418
#define DMA_TRANS_STATUS_OFFSET            0x41C
#define DMA_TRANS_DIR_OFFSET            0x420
#define SQC_SAO_OFFSET                0x600
#define SQC_CMD_OFFSET                0x608
#define SQC_STATUS_OFFSET            0x60C
#define SQC_CAO_OFFSET                0x610
#define SQC_REG_CTRL_OFFSET            0x614
#define SQC_REG_VAL_OFFSET            0x618
#define SQC_BRPAO0_OFFSET            0x620
#define SQC_BRPAO1_OFFSET            0x624
#define INTC_SQC_CLR_OFFSET            0x1000
#define INTC_DMA_CLR_OFFSET            0x1004
#define INTC_ONENAND_CLR_OFFSET            0x1008
#define INTC_SQC_MASK_OFFSET            0x1020
#define INTC_DMA_MASK_OFFSET            0x1024
#define INTC_ONENAND_MASK_OFFSET        0x1028
#define INTC_SQC_PEND_OFFSET            0x1040
#define INTC_DMA_PEND_OFFSET            0x1044
#define INTC_ONENAND_PEND_OFFSET        0x1048
#define INTC_SQC_STATUS_OFFSET            0x1060
#define INTC_DMA_STATUS_OFFSET            0x1064
#define INTC_ONENAND_STATUS_OFFSET        0x1068

/*
 * Memory controller
 */
#define ELFIN_SROM_BASE            0xE8000000

#define SROM_BW_REG            __REG(ELFIN_SROM_BASE+0x0)
#define SROM_BC0_REG            __REG(ELFIN_SROM_BASE+0x4)
#define SROM_BC1_REG            __REG(ELFIN_SROM_BASE+0x8)
#define SROM_BC2_REG            __REG(ELFIN_SROM_BASE+0xC)
#define SROM_BC3_REG            __REG(ELFIN_SROM_BASE+0x10)
#define SROM_BC4_REG            __REG(ELFIN_SROM_BASE+0x14)
#define SROM_BC5_REG            __REG(ELFIN_SROM_BASE+0x18)

/*
 * SDRAM Controller
 */
#define APB_DMC_0_BASE            0xF0000000
#define APB_DMC_1_BASE            0xF1400000
#define ASYNC_MSYS_DMC0_BASE        0xF1E00000

#define DMC_CONCONTROL             0x00
#define DMC_MEMCONTROL             0x04
#define DMC_MEMCONFIG0             0x08
#define DMC_MEMCONFIG1             0x0C
#define DMC_DIRECTCMD             0x10
#define DMC_PRECHCONFIG         0x14
#define DMC_PHYCONTROL0         0x18
#define DMC_PHYCONTROL1         0x1C
#define DMC_RESERVED             0x20
#define DMC_PWRDNCONFIG         0x28
#define DMC_TIMINGAREF             0x30
#define DMC_TIMINGROW             0x34
#define DMC_TIMINGDATA             0x38
#define DMC_TIMINGPOWER         0x3C
#define DMC_PHYSTATUS             0x40
#define DMC_CHIP0STATUS         0x48
#define DMC_CHIP1STATUS         0x4C
#define DMC_AREFSTATUS             0x50
#define DMC_MRSTATUS             0x54
#define DMC_PHYTEST0             0x58
#define DMC_PHYTEST1             0x5C
#define DMC_QOSCONTROL0         0x60
#define DMC_QOSCONFIG0             0x64
#define DMC_QOSCONTROL1         0x68
#define DMC_QOSCONFIG1             0x6C
#define DMC_QOSCONTROL2         0x70
#define DMC_QOSCONFIG2             0x74
#define DMC_QOSCONTROL3         0x78
#define DMC_QOSCONFIG3             0x7C
#define DMC_QOSCONTROL4         0x80
#define DMC_QOSCONFIG4             0x84
#define DMC_QOSCONTROL5         0x88
#define DMC_QOSCONFIG5             0x8C
#define DMC_QOSCONTROL6         0x90
#define DMC_QOSCONFIG6             0x94
#define DMC_QOSCONTROL7         0x98
#define DMC_QOSCONFIG7             0x9C
#define DMC_QOSCONTROL8         0xA0
#define DMC_QOSCONFIG8             0xA4
#define DMC_QOSCONTROL9         0xA8
#define DMC_QOSCONFIG9             0xAC
#define DMC_QOSCONTROL10         0xB0
#define DMC_QOSCONFIG10         0xB4
#define DMC_QOSCONTROL11         0xB8
#define DMC_QOSCONFIG11         0xBC
#define DMC_QOSCONTROL12         0xC0
#define DMC_QOSCONFIG12         0xC4
#define DMC_QOSCONTROL13         0xC8
#define DMC_QOSCONFIG13         0xCC
#define DMC_QOSCONTROL14         0xD0
#define DMC_QOSCONFIG14         0xD4
#define DMC_QOSCONTROL15         0xD8
#define DMC_QOSCONFIG15         0xDC


/*
* Memory Chip direct command
*/

/****************************************************************
 Definitions for memory configuration
 Set memory configuration
    active_chips     = 1'b0 (1 chip)
    qos_master_chip  = 3'b000(ARID[3:0])
    memory burst     = 3'b010(burst 4)
    stop_mem_clock     = 1'b0(disable dynamical stop)
    auto_power_down  = 1'b0(disable auto power-down mode)
    power_down_prd     = 6'b00_0000(0 cycle for auto power-down)
    ap_bit         = 1'b0 (bit position of auto-precharge is 10)
    row_bits     = 3'b010(# row address 13)
    column_bits     = 3'b010(# column address 10 )

 Set user configuration
    2'b10=SDRAM/mSDRAM, 2'b11=DDR, 2'b01=mDDR

 Set chip select for chip [n]
     row bank control, bank address 0x3000_0000 ~ 0x37ff_ffff
     CHIP_[n]_CFG=0x30F8,  30: ADDR[31:24], F8: Mask[31:24]
******************************************************************/

#define INF_REG_BASE            0xE010F000

#define INF_REG0_REG            __REG(INF_REG_BASE+INF_REG0_OFFSET)
#define INF_REG1_REG            __REG(INF_REG_BASE+INF_REG1_OFFSET)
#define INF_REG2_REG            __REG(INF_REG_BASE+INF_REG2_OFFSET)
#define INF_REG3_REG            __REG(INF_REG_BASE+INF_REG3_OFFSET)
#define INF_REG4_REG            __REG(INF_REG_BASE+INF_REG4_OFFSET)
#define INF_REG5_REG            __REG(INF_REG_BASE+INF_REG5_OFFSET)
#define INF_REG6_REG            __REG(INF_REG_BASE+INF_REG6_OFFSET)
#define INF_REG7_REG            __REG(INF_REG_BASE+INF_REG7_OFFSET)

#define NFCONF_VAL    (7<<12)|(7<<8)|(7<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0)
#define NFCONT_VAL      (0x1<<23)|(0x1<<22)|(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x2<<1)|(1<<0)
#define MP03CON_VAL    (1<<29)|(1<<25)|(1<<21)|(1<<17)|(1<<13)|(1<<9)|(1<<5)|(1<<1)

#define ELFIN_TZPC0_BASE        0xF1500000
#define ELFIN_TZPC1_BASE        0xFAD00000
#define ELFIN_TZPC2_BASE        0xE0600000
#define ELFIN_TZPC3_BASE        0xE1C00000

sdram_init.S

#include "s5pv210.h"

#if 1
#define DMC0_MEMCONTROL        0x00202400     // MemControl    BL=4, 1Chip, DDR2 Type, dynamic self refresh, force precharge, dynamic power down off

#define DMC0_MEMCONFIG_0    0x20F01323    // MemConfig0    256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_1    0x30F00312    // MemConfig1        默认值

#define DMC0_TIMINGA_REF    0x00000618    // TimingAref    7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
#define DMC0_TIMING_ROW        0x28233287    // TimingRow    for @200MHz
#define DMC0_TIMING_DATA    0x23240304    // TimingData    CL=3
#define    DMC0_TIMING_PWR        0x09C80232    // TimingPower

#define    DMC1_MEMCONTROL        0x00202400    // MemControl    BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off

#define DMC1_MEMCONFIG_0    0x40F01323    // MemConfig0    512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC1_MEMCONFIG_1    0x60E00312    // MemConfig1

#define DMC1_TIMINGA_REF    0x00000618    // TimingAref    7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4
#define DMC1_TIMING_ROW        0x28233289    // TimingRow    for @200MHz
#define DMC1_TIMING_DATA    0x23240304    // TimingData    CL=3
#define    DMC1_TIMING_PWR        0x08280232    // TimingPower

#endif

#if 0

#define DMC0_MEMCONTROL        0x00212400     // MemControl    BL=4, 1Chip, DDR2 Type, dynamic self refresh, force precharge, dynamic power down off

#define DMC0_MEMCONFIG_0    0x20E01323    // MemConfig0    512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_1    0x40F01323    // MemConfig1

#define DMC0_TIMINGA_REF    0x00000618    // TimingAref    7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
#define DMC0_TIMING_ROW        0x28233287    // TimingRow    for @200MHz
#define DMC0_TIMING_DATA    0x23240304    // TimingData    CL=3
#define    DMC0_TIMING_PWR        0x09C80232    // TimingPower

#define    DMC1_MEMCONTROL        0x00202400    // MemControl    BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off

#define DMC1_MEMCONFIG_0    0x40C01323    // MemConfig0    512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC1_MEMCONFIG_1    0x00E01323    // MemConfig1

#define DMC1_TIMINGA_REF    0x00000618    // TimingAref    7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4
#define DMC1_TIMING_ROW        0x28233289    // TimingRow    for @200MHz
#define DMC1_TIMING_DATA    0x23240304    // TimingData    CL=3
#define    DMC1_TIMING_PWR        0x08280232    // TimingPower


#endif







.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初始化步骤
/*******************************************************************************************/    
// 下面是DRAM1初始化步骤,两者没有联系,是并列的。

    /* DMC1 initialization */
    ldr    r0, =APB_DMC_1_BASE
    ldr    r1, =0x00101000                @Phycontrol0 DLL parameter setting
    str    r1, [r0, #DMC_PHYCONTROL0]

    
    ldr    r1, =0x00000086                @Phycontrol1 DLL parameter setting
    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_val1:
    ldr    r1, [r0, #DMC_PHYSTATUS]        @Load Phystatus register value
    and    r2, r1, #0x7
    cmp    r2, #0x7                @Loop until DLL is locked
    bne    find_lock_val1
    
    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

    /* settinf fot DDR2 */
    ldr    r0, =APB_DMC_1_BASE

    ldr    r1, =0x0FFF2010                @auto refresh off
    str    r1, [r0, #DMC_CONCONTROL]

    ldr    r1, =DMC1_MEMCONTROL            @MemControl    BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
    str    r1, [r0, #DMC_MEMCONTROL]

    ldr    r1, =DMC1_MEMCONFIG_0            @MemConfig0    512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
    str    r1, [r0, #DMC_MEMCONFIG0]

    ldr    r1, =DMC1_MEMCONFIG_1            @MemConfig1
    str    r1, [r0, #DMC_MEMCONFIG1]

    ldr    r1, =0xFF000000
    str    r1, [r0, #DMC_PRECHCONFIG]

    ldr    r1, =DMC1_TIMINGA_REF            @TimingAref    7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4
    str    r1, [r0, #DMC_TIMINGAREF]

    ldr    r1, =DMC1_TIMING_ROW            @TimingRow    for @200MHz
    str    r1, [r0, #DMC_TIMINGROW]

    ldr    r1, =DMC1_TIMING_DATA            @TimingData    CL=3
    str    r1, [r0, #DMC_TIMINGDATA]

    ldr    r1, =DMC1_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, =0x00110440                @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, =DMC1_MEMCONTROL            @MemControl    BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
    str    r1, [r0, #DMC_MEMCONTROL]
    // 函数返回
    mov pc, lr

Makefile

需要加如一个文件名字

$(OUT_NAME).bin: start.o led.o sdram_init.o

结束




Copyright © 2026 Y 版权所有.网站运行:13年238天21小时26分