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

如果是SROM/NAND/ONENAND则接port0
如果是DDR2/mDDR/mDDR则接port1/port2
对比手册:


原理图中每个DDR端口都由3类总线构成:地址总线( Xmn ADDRO~XMnADDR13共1 4根地址总线) +控制总线.. (. 中间部分自己看原理图)... +数据总线(Xmn DATAO~XMnDATA31共32根数据线)
分析:从数据总线的位数可以看出,我们用的是32位的(物理)内存。

原理图中画出4片内存芯片的一一页,可以看出: X210开发板共使用了4片内存( 每片1Gb=128MB,共512MB) ,每片内存的数据总线都是16位的( 单芯片是16位内存)
如何使用16位内存得到32位内存呢?可以使用并联的方式。在原理图上横向的两颗内存芯片就是并联的。两个芯片加起来成了一个芯片,两个共同组成了三十二位。
并联时,地址总线接法一致,但是数据总线要加起来,这样链接相当于在逻辑上可以把这2颗芯片看成是一个(这一个芯片是32位的,接在xm1端口上)
读数据手册

看数据手册:NT5TU64M16GG-DDR2-1G-G-R18-Consumer.pdf
第十页Block Diagram
这个框图是64Mb*16结构的,指的是8bank,每bank128mBit。

上图和下图对应
210的DDR端口信号中有BA0~BA2,接在内存芯片的BAO~ -BA2上,这些引脚就是用来选择bank的。3个引线就是2三次方,有八个组合。
128Mb通过横向和纵向寻址

通过旁边划线的数字来区分多少位
每个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, lrsdram_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,就是2Xs5pv210.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
驱动强度
参考代码里面这里的信息是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:
- 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. - 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. - DQS Cleaning: Set the PhyControl1.ctrl_shiftc and PhyControl1.ctrl_offsetc bit-fields to correct value
according to clock frequency and memory tAC parameters. - Set the PhyControl0.ctrl_start bit-field to ‘1’.
- Set the ConControl. At this moment, an auto refresh counter should be off.
- Set the MemControl. At this moment, all power down modes should be off.
- Set the MemConfig0 register. If there are two external memory chips, set the MemConfig1 register.
- Set the PrechConfig and PwrdnConfig registers.
- Set the TimingAref, TimingRow, TimingData and TimingPower registers according to memory AC
parameters. - If QoS scheme is required, set the QosControl0~15 and QosConfig0~15 registers.
- Wait for the PhyStatus0.ctrl_locked bit-fields to change to ‘1’. Check whether PHY DLL is locked.
- 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. - Confirm whether stable clock is issued minimum 200us after power on
- Issue a NOP command using the DirectCmd register to assert and to hold CKE to a logic high level.
- Wait for minimum 400ns.
- Issue a PALL command using the DirectCmd register.
- Issue an EMRS2 command using the DirectCmd register to program the operating parameters.
- Issue an EMRS3 command using the DirectCmd register to program the operating parameters.
- Issue an EMRS command using the DirectCmd register to enable the memory DLLs.
- Issue a MRS command using the DirectCmd register to reset the memory DLL.
- Issue a PALL command using the DirectCmd register.
- Issue two Auto Refresh commands using the DirectCmd register.
- Issue a MRS command using the DirectCmd register to program the operating parameters without resetting
the memory DLL. - Wait for minimum 200 clock cycles.
- 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. - If there are two external memory chips, perform steps 14~25 for chip1 memory device.
- 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 offldr 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
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)
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)

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

根据十七步骤的方法,发送的命令需要顺序:
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 0xE1C00000sdram_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, lrMakefile
需要加如一个文件名字
$(OUT_NAME).bin: start.o led.o sdram_init.o