U-Boot-内存部分

Posted _WILLPOWER_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了U-Boot-内存部分相关的知识,希望对你有一定的参考价值。

参考国嵌

内存的分类

SRAM

SRAM:它是一种具有静止存取功能的内存,不需要定期刷新电路就能保存它内部存储的数据。其优点:存取速度快;但是缺点是:功耗大,成本高。常用作存储容量不高,但存取速度快的场合,比如steppingstone.

SDRAM

SDRAM(Synchronous Dynamic Random Access Memory)
同步: 内存工作需要有同步时钟,内部的命令的发送
与数据的传输都以该时钟为基准。
动态: 存储阵列需要不断的刷新来保证数据不丢失。
随机: 是指数据不是线性依次存储,而是自由指定地
址进行数据读写。
备注:2440开发板上使用的内存通常是SDRAM.

DDR(Double Data Rate SDRAM)

“双倍速率同步动态随机存储器”。
与早期的SDRAM相比,DDR除了可以在时钟脉冲的上升沿传输数据,还可以在下降沿传输信号,这意味着在相同的工作频率下,DDR的理论传输速率为SDRAM的两倍。
DDR2则在DDR的基础上再次进行了改进,使得数据传输速率在DDR的基础上再次翻倍。
备注:6410开发板通常采用DDR内存
210开发板通常采用DDR2内存

在嵌入式硬件体系中,除了CPU内部的"steppingstone"采用SRAM外,板载内存一般会采用DRAM,而DRAM又可以分为SDRAM,DDR,DDR2等。

DRAM

DRAM:它的基本原件是小电容,电容可以在两个极板上保留电荷,但是需要定期的充电(刷新),否则数据会丢失。缺点:由于要定期刷新存储介质,存取速度较慢。

内存的内部结构

内存的内部如同表格,数据就存放在每个单元格中。数据读写时,先指定行号(行地址),再指定列号(列地址),我们就可以准确地找到所需要的单元格。而这张表格的称为:
Logical Bank(L-Bank).

由于技术、成本等原因,一块内存不可能把所有的单元格都做到一个L-Bank,现在内存内部基本都会分割成4个L-Bank。

寻址信息

  1. L-Bank选择信号
  2. 行地址
  3. 列地址

2440内存初始化

27根地址线

8个片选信号

为了扩大外设的访问范围,S3c2440芯片提供了8个片选信号
nGCS0~nGCS7
当某个片选信号nGCSx有效时,则可以通过27根地址线去访问对应这个片选的128MB空间。
由于有8个片选,所以2440芯片能访问的外设空间总共为8*128MB=1GB而1G(Ox40000000)以上的空间,则安排给了2440内部的寄存器,访问这些内部的寄存器,则是通过32位的处理器内部总线来完成的。

使用芯片为HY57V561621

存储控制器


因为没有使用bank7的UB/LB因此31位为0,等待状态设置为0,因此30位为0,因为是将两个16位的内存芯片,然后拼成的32位的,因此29:28设置为10
同样bank6和bank7一样,都是连接sdram,因此值一样,后面的5-0都还没有使用,全部保持为0,因此总的值为0x22000000


没有用到bank0-5,因此值不变都为0x0700


首先16:15位决定是什么类型,因为我们这里是sdram因此设置为11
因为用的SDRAM因此只用设置0-3位
首先是设定延时是几个始终

这里应该设置为2个时钟,为00
后面的SCAN是设置为列地址数,通过HY576这个芯片手册

这里应该设置为9位,01
0x11000000000000001=0x18001


然后是负责刷新的控制寄存器

23位设置为1要刷新
22位设置为0自动刷新
21:20设置为00两个时钟

19:18设置为11一行刷新时间通常为17个时钟
17:16设置为00不使用的
15:11设置为00000也是不使用的
10:0刷新周期设置

要根据HCLOCK设置,是核频率的1/4也就是100MHZ,因此设置为1269就是了
也就是10011110101
因此总的下来这个寄存器应该设置为0x8c04F5

7位控制ARM core突发模式操作是否使用,一般设置为1
6位未用为0
5位掉电模式打开设置位1
4位设置位1
3位为0
2:0bank大小设置因此设置为00164M
总的下来设置为0xb1


设置bank6和bank7的模式设置(设置一个其余一个相同即可)
只需要设置CL域就行了
是用来设置CAS延迟,根据图来

指的是从RAS变低到CAS变低的时钟数,这里是三个时钟
因此为011其余全部为0
因此总的为0x30同样bank7对应的也一样

6410内存初始哈

地址空间

S3C6410处理器拥32位地址总线,其寻址空间为4GB。其中高2GB为保留区,低2GB区域又可划分为两部分:主存储区和外设区。

主存储区划分

外设区存放着寄存器这些,主存储区是内存和boot这些

内存芯片连接

6410的芯片是用的两片128M内存组成的256M的。

初始化流程

  • memc cmd设置到’b100。使DRAM控制器进入“Config”状态。

  • 芯片配置和id配置寄存器以及时隙参数等。

  • 等待200us允许SDRAM电源和时钟稳定。然而,当CPU开始工作时,电源和时钟已经稳定了(这个工作可以不做)

  • 执行内存初始化序列。(因为使用的是ddr的内存,因此选择第二个)

  • 将memc cmd编程为b000,使DRAM控制器进入’Ready’状态

  • 检查memc stat中的内存状态字段,直到内存状态变为b01,即’Ready’。

在最前面其实有一步,设置引脚为data pin

代码


检查最后两位是否为ready 01

210内存初始化

地址空间


0地址也是映射区

内存芯片连接

210开发板的内存通常采用8片或者4片128M*8bit芯片级联的办法。

初始化

为了支持高速存储设备,DRAM控制器使用SEC DDR PHY接口。该控制器包括一个先进的嵌入式调度器,以有效地利用内存设备和优化的管道阶段,以减少延迟。S5PV210有两个独立的DRAM控制器和端口。DMCO和一代。DMCO最大支持512MByte和DMC1 1GByte内存大小,但两个控制器必须使用相同类型的内存

这里采用初始化DRAM 0
采用的是DDR2


DDR2内存类型的初始化顺序:

  1. 为了为控制器和存储设备提供稳定的电源,控制器必须断言并保持CKE到逻辑低电平。然后应用稳定时钟。注意:XDDR2SEL应该是高电平,以保持CKE为低。

  2. 设置PhyControl0.ctrl_start_point和PhyControl0.ctrl_inc位域根据时钟频率来校正值。设置PhyControl0.ctrl_dll_on bit-field to '1’打开PHY DLL

  3. DQS清洗:设置PhyControl1.ctrl_shiftc和 PhyControl1.ctrl_offsetc 位域,根据时钟频率和内存tAC参数来校正值。(因为现在只用DRAM 0,因此1暂时不管)

  4. 设置PhyControl0.ctrl_start位域为’1

  5. 设置ConControl。此时,自动刷新计数器应该关闭(默认值即可)。

  6. 设置MemControl。此时,所有的关机模式都应该关闭。

  7. 设置MemConfig0寄存器。如果有两个外部内存芯片,设置MemConfig 1寄存器。

  8. 设置 PrechConfig和PwrdnConfig寄存器。

  9. 根据内存交流参数设置TimingAref、TimingRow、TimingData和TimingPower寄存器



  10. 如果需要QoS方案,则设置QosControl0-15和QosConfig0-15寄存器。

  11. 等待PhyStatus0.ctrl_locked位域为’1’。检查PHY DLL是否为locked

  12. PHY DLL补偿内存运行过程中由于进程、电压和温度(PVT)变化而引起的延迟量的变化。因此,为了可靠的运行,PHY DLL不应该关闭。除了低频运行外,它可以关闭。如果使用off模式,请设置PhyControl0.ctrl_force bit-field根据PhyStatus0.ctrl_lock_value[9:2]字段修正延迟量。清除PhyControl0.ctrl_dll_on bit-field关闭PHY DLL。

  13. 确认开机后是否发出稳定时钟最小200us

  14. 使用DirectCmd寄存器发出NOP命令来断言并将CKE保持在一个逻辑高级。

  15. 等待最小400ns

  16. 使用DirectCmd注册器发出PALL命令

  17. 使用DirectCmd寄存器发出EMRS2命令来编写运行参数。

  18. 使用DirectCmd寄存器发出EMRS3命令来编写运行参数。

  19. 使用DirectCmd注册器发出EMRS命令来启用内存dll

  20. 使用DirectCmd寄存器发出MRS命令来重置内存DLLs。

  21. 使用DirectCmd注册器发出PALL命令

  22. 使用DirectCmd寄存器发出两个自动刷新命令。

  23. 使用DirectCmd寄存器发出MRS命令来编程运行参数,而不重置内存DLL。

  24. 等待至少200个时钟周期。

  25. 使用DirectCmd寄存器发出EMRS命令来编写运行参数。如果不使用OCD校准,可通过EMRS命令设置“OCD校准默认值”。之后,发出EMRS命令退出OCD校准模式,并对运行参数进行编程

  26. 如果有2个外置内存芯片,则对“chip1”内存设备执行14-25

  27. 将control设置为打开自动刷新计数器。

  28. 如果需要掉电模式,请设置MemControl寄存器。

mem.S


#define DMC_PHYCONTROL0 0xf0000018
#define DMC_PHYCONTROL1 0xf000001c
#define DMC_CONCONTROL  0xf0000000
#define DMC_MEMCONTROL  0xf0000004
#define DMC_MEMCONFIG0  0xf0000008
#define DMC_MEMCONFIG1  0xf000000c
#define DMC_PRECHCONFIG 0xf0000014
#define DMC_TIMINGAREF 	0xf0000030
#define DMC_TIMINGROW 	0xf0000034
#define DMC_TIMINGDATA 	0xf0000038
#define DMC_TIMINGPOWER 0xf000003c
#define DMC_PHYSTATUS   0xf0000040
#define DMC_DIRECTCMD 	0xf0000010
#define DMC_PWRDNCONFIG 0xf0000028

#define DMC0_MEMCONTROL			0x00202400
#define DMC0_MEMCONFIG_0		0x20F00313	
#define DMC0_MEMCONFIG_1		0x00F00313	

#define DMC0_TIMINGA_REF        0x00000618
#define DMC0_TIMING_ROW         0x2B34438A
#define DMC0_TIMING_DATA        0x24240000
#define DMC0_TIMING_PWR         0x0BDC0343      

.globl mem_init
mem_init:
	@ step 2.1
	ldr	r0, =DMC_PHYCONTROL0
	ldr	r1, =0x00101000				
	str	r1, [r0]
	
	@ step 2.2
	ldr	r0, =DMC_PHYCONTROL0
	ldr	r1, =0x00101002					
	str	r1, [r0]
	
	@ step 4
	ldr	r0, =DMC_PHYCONTROL0
	ldr	r1, =0x00101003					
	str	r1, [r0]
	
	@ step 5
	ldr	r0, =DMC_CONCONTROL				
	ldr	r1, =0x0FFF1350
	str	r1, [r0]
	
	@ step 6
	ldr	r0, =DMC_MEMCONTROL
	ldr	r1, =DMC0_MEMCONTROL				
	str	r1, [r0]
	
	@ step 7
	ldr	r0, =DMC_MEMCONFIG0
	ldr	r1, =DMC0_MEMCONFIG_0				
	str	r1, [r0]
	
	@ step 8
	ldr	r0, =DMC_PRECHCONFIG
	ldr	r1, =0xFF000000					
	str	r1, [r0]
	
	@ step 9.1
	ldr	r0, =DMC_TIMINGAREF
	ldr	r1, =DMC0_TIMINGA_REF				
	str	r1, [r0]
	
	@ step 9.2
	ldr	r0, =DMC_TIMINGROW
	ldr	r1, =DMC0_TIMING_ROW				
	str	r1, [r0]
	
	@ step 9.3
	ldr	r0, =DMC_TIMINGDATA
	ldr	r1, =DMC0_TIMING_DATA				
	str	r1, [r0]
	
	@ step 9.4
	ldr	r0, =DMC_TIMINGPOWER
	ldr	r1, =DMC0_TIMING_PWR				
	str	r1, [r0]
	
	@ step 11
wait_lock:
	ldr	r0, =DMC_PHYSTATUS 
	ldr	r1, [r0]			
	and	r2, r1, #0x4
	cmp	r2, #0x4					
	bne	wait_lock

	@ step 14
	ldr	r0, =DMC_DIRECTCMD
	ldr	r1, =0x07000000					
	str	r1, [r0]
	
	@ step 16
	ldr	r1, =0x01000000					
	str	r1, [r0]
	
	@ step 17
	ldr	r1, =0x00020000					
	str	r1, [r0]
	
	@ step 18
	ldr	r1, =0x00030000					
	str	r1, [r0]
	
	@ step 19
	ldr	r1, =0x00010400					
	str	r1, [r0]
	
	@ step 20
	ldr	r1, =0x00000542					
	str	r1, [r0]
	
	@ step 21
	ldr	r1, =0x01000000					
	str	r1, [r0]
	
	@ step 22.1 
	ldr	r1, =0x05000000					
	str	r1, [r0]
	
	@ step 22.2
	ldr	r1, =0x05000000					
	str	r1, [r0]
	
	@ step 23
	ldr	r1, =0x00000442					
	str	r1, [r0]
	
	@ step 25.1
	ldr	r1, =0x00010780					
	str	r1, [r0]
	
	@ step 25.2
	ldr	r1, =0x00010400					
	str	r1, [r0]
	
	@ step 26, repeat step14~step25
	ldr	r1, =0x07100000					
	str	r1, [r0]
	
	ldr	r1, =0x01100000					
	str	r1, [r0]
	
	ldr	r1, =0x00120000					
	str	r1, [r0]
	
	ldr	r1, =0x00130000					
	str	r1, [r0]
	
	ldr	r1, =0x00110400					
	str	r1, [r0]
	
	ldr	r1, =0x00100542					
	str	r1, [r0]
	
	ldr	r1, =0x01100000					
	str	r1, [r0]
	
	ldr	r1, =0x05100000					
	str	r1, [r0]
	
	ldr	r1, =0x05100000					
	str	r1, [r0]
	
	ldr	r1, =0x00100442					
	str	r1, [r0]
	
	ldr	r1, =0x00110780					
	str	r1, [r0]
	
	ldr	r1, =0x00110400					
	str	r1, [r0]
	
	@ step 27
	ldr     r0, =DMC_CONCONTROL
	ldr	r1, =0x0FF02030					
	str	r1, [r0]
	
	ldr     r0, =DMC_PWRDNCONFIG
	ldr	r1, =0xFFFF00FF					
	str	r1, [r0]
	
	ldr     r0, =DMC_CONCONTROL
	ldr	r1, =0x00202400					
	str	r1, [r0]

	mov	pc, lr

以上是关于U-Boot-内存部分的主要内容,如果未能解决你的问题,请参考以下文章

u-boot的内存分布和全局数据结构

十u-boot 调试--串口修改

U-boot 启动内核

U-Boot命令之内存操作命令

u-boot 启动过程

Linux嵌入式驱动学习之路⑤u-boot启动流程分析