uboot-step 8 内存初始化

uboot-step 8 内存初始化

内存的初始化相比前面的那些步骤略微的麻烦了些,为了能够比较清楚地说明下内存的初始化,(ps:虽然我也不是特别的清楚),首先简单的说下这篇文章的大概流程:

  • 1.对内存相关的一些简单介绍
  • 2.s3c6410的内存控制器的初始化流程
  • 3.对照datasheet说明实现代码的工作流程

关于内存

内存的分类

这里所说的内存仅指RAM(RandomAccessMemory,随机存取存储器),它具有可以随机读写访问的特点,并且存储的数据在断电后会自动消失,现在所用的主要有以下两种类型:

  • SRAM :静态RAM,不需要一直刷新,双稳态电路形式存储数据,集成度较低,体积大,造价高,容量小,通常用作Cache
  • DRAM : 动态RAM, 需要不断刷新,通过MOS电容存储电荷来存储数据,结构简单,集成度高,成本低,便于大容量制造,常见的几种DRAM:
    • SDRAM :Synchronous Dynamic RAM ,同步动态随机存储器,工作频率与系统的频率相同,逐渐被DDR SDRAM所取代
    • DDR SDRAM : Double Data Rate SDRAM 双倍同步动态随机存储器,习惯上称之为DDR,相比SDRAM,速度和容量上有所提升,本质上虽然没有提高时钟频率,但是可以在时钟的上升沿和下降沿同时传输数据,因此其速度是标准SDRAM 的两倍
    • mobile DDR : 相比pC端的DDR,电压更低,封装更小

内存的结构

内存的内部结构就像表格一样,每一张表格称为一个逻辑BANK,L_BANK,每张表格有若干行地址线和若干列地址线,寻址的时候,首先去找到数据在哪一个bank里面,然后在分别确定行地址和列地址,这样就可以找到需要的数据所在的单元了,由于成本,制造工艺的原因,无法将整个地址空间做到一个bank里面,现在一般都将整个地址空间分为4个L-bank,四个L-bank具有公用的行地址和列地址


uboot-step 8 内存初始化_第1张图片
bank.png

内存的容量

Ram.png

一般内存容量的表示方法如上图所示,64M表示有多少个存储单元,32表示每个存储单位的容量为多少bit,可以将其换算为Byte,如上图所示的内存容量为64M 32bit=644Byte=256MByte。

内存引脚说明

uboot-step 8 内存初始化_第2张图片
rampin.png

如上图所示,RAM的引脚主要有以下几种:

  • 电源引脚: 数据电源VDDQ,VSSQ,电源VDD,VSS
  • 时钟相关引脚: CK 上升沿和下降沿两个,CKE时钟使能引脚
  • 片选引脚: CS 低有效
  • 列,行地址,写使能引脚: 列,行地址选中使能,写使能引脚,低有效
  • DMx引脚:输入数据屏蔽引脚
  • BA0,1:bank选择引脚
  • A[n:0]:地址线
  • DQ:数据总线
  • DQSx:输出数据闸门

下图是S3c6410 内存端口引脚说明,可以看出与上面的内存芯片的datasheet中的引脚说明正好一一对应


uboot-step 8 内存初始化_第3张图片
rampin1.png

硬件原理图如下图所示:


uboot-step 8 内存初始化_第4张图片
ramsch.png

更多内存相关的知识请找度娘或参考下面的链接
终极图解内存上
终极图解内存下

s3c6410 DRAMC初始化流程

S3c6410的DRAM 控制器支持SDR SDRAM,mobile SDR SDRAM ,DDR SDRAM,和mobile DDR SDRAM多种类型,根据芯片手册上的描述:
DRAM 控制器支持多达两片同样类型的最大256M的内存,所有的内存片都共享同样的引脚,除了时钟使能和片选信号,当上电复位以后,软件必须初始化DRAM控制器和连接到DRAM控制器上的内存,初始化流程需要参考SDRAM datasheet,可供参考的初始化流程如下图,第一张图是DRAM 控制器的初始化流程,第二张图是内存的初始化流程:


uboot-step 8 内存初始化_第5张图片
Dram1.png

uboot-step 8 内存初始化_第6张图片
DRAM2.png

由于所采用的开发板上的内存芯片为Mobile DDR SDRAM,因此这里只贴出了这种类型的内存初始化流程,先来看下DRAM控制器的初始化流程:

  • 1.编程memc_cmd 写入'3b100',使DRAM控制器进入Config (配置)状态
  • 2.向相关的寄存器中写入内存时序参数,内存片的配置,id配置相关
  • 3.等待200us,使内存上电和时钟稳定,但是其实当cpu开始工作的时候,内存电源和时钟都已经稳定了
  • 4.执行内存初始化流程,即下面的流程
  • 5.编程memc_cmd写入'3b000',使DRAM控制器进入’Ready‘(准备)状态
  • 6.检查寄存器memc_stat 内存状态域直到内存状态为’2b01‘,这意味着DRAM控制器已经准备好了

看完了DRAM控制器的初始化流程,再来看下内存初始化的流程:

  • 1.编程mem_cmd 在direct_cmd 写入’2b11‘,使DRAM控制器发送'NOP'命令到内存
  • 2.编程mem_cmd 在direct_cmd 写入’2b00‘,使内存控制器发送’Prechargeall'命令到内存
  • 3.编程mem_cmd 在direct_cmd 写入‘2b11’,使DRAM控制器发送'Autorefresh'命令到内存
  • 4.编程mem_cmd 在direct_cmd 写入‘2b11’,使DRAM控制器发送'Autorefresh'命令到内存
  • 5.编程mem_cmd '2b10'在direct_cmd,使DRAM 控制器发送MRS内存命令-EMRS的bank地址一定要设定
  • 6.编程mem_cmd '2b10'在direct_cmd,使DRAM 控制器发送MRS内存命令-MRS的bank地址一定要设定

接下来按照上面的流程来进行内存的初始化

1,Dram控制器进入配置状态
uboot-step 8 内存初始化_第7张图片
memc_cmd.png

按照上图的说明,向memc_cmd寄存器中写入100即可

2,内存时序参数,id等相关配置
  • Refresh period 配置


    uboot-step 8 内存初始化_第8张图片
    refresh period.png

    内存刷新周期设置,根据下图内存芯片手册的值,由s3c6410的时钟体系配置,内存使用的为AHB总线时钟,为133Mhz,7.8us对应寄存器的值应为7800*(1000 000 000/133 000 000),此值不是一个整数,最后在加上1,即为寄存器中的值


    data refresh.png
  • CAS latency


    uboot-step 8 内存初始化_第9张图片
    cas.png

    如下图,内存芯片手册上的数字为2或3,这里设为3


    data cas.png
  • t_DQSS


    uboot-step 8 内存初始化_第10张图片
    t_dqss.png

    如下图,内存芯片手册上的为0.75到1.25之间,这里设为1


    data tdqss.png
  • t_MRD


    uboot-step 8 内存初始化_第11张图片
    t mrd.png

    如下图,内存芯片手册上的为2

data tmrd.png
  • t_RAS


    uboot-step 8 内存初始化_第12张图片
    t_ras.png

    如下图,内存芯片手册上的为40 到70000ns之间,我们大概选个时间就好


    data tras.png
  • t_RC


    uboot-step 8 内存初始化_第13张图片
    t_rc.png
  • t_RCD


    uboot-step 8 内存初始化_第14张图片
    t_rcd.png
  • t_RFC


    t_rfc.png
  • t_RP


    t_rp.png
  • t_RRD


    t_rrd.png
  • t_WR


    uboot-step 8 内存初始化_第15张图片
    t_wr.png
  • t_WTR


    uboot-step 8 内存初始化_第16张图片
    t_wtr.png
  • t_XP


    uboot-step 8 内存初始化_第17张图片
    t_xp.png
  • t_XSR


    uboot-step 8 内存初始化_第18张图片
    t_xsr.png
  • t_ESR


    uboot-step 8 内存初始化_第19张图片
    t_esr.png

上面这些时序参数配置大部分在内存芯片手册上都可以找到,只要相应的填进去就好,实在没有的可以参考其它人的代码来写:


uboot-step 8 内存初始化_第20张图片
data sheet.png

data sheet1.png
  • MEMCFG 寄存器 行列地址,burst length,内存片数量


    uboot-step 8 内存初始化_第21张图片
    memcfg.png

    uboot-step 8 内存初始化_第22张图片
    memcfg1.png

    这里内存芯片只有一片,芯片手册上相关数据如下:


    data addr.png

    data burst.png
  • MEMCFG2 寄存器 配置,内存类型,数据宽度等信息,这里32bit,mobileDDR内存


    uboot-step 8 内存初始化_第23张图片
    memcfg2.png
  • chipcfg 配置AXI 内存地址


    uboot-step 8 内存初始化_第24张图片
    chipcfg.png
  • usrcfg 用户寄存器


    uboot-step 8 内存初始化_第25张图片
    usrcfg.png
3.这样就完成了内存参数的设置,下面进行内存初始化流程
uboot-step 8 内存初始化_第26张图片
directcmd.png
  • 1、发送NOP命令
  • 2、发送Prechargeall命令
  • 3、发送Autofresh
  • 4、发送Autofresh
  • 5、发送mrs命令,设置mrs寄存器
  • 6、发送mrs命令,设置emrs寄存器
    对于5,6点的内存寄存器的设置需要根据内存芯片手册进行相关配置,如下图:


    uboot-step 8 内存初始化_第27张图片
    data mrs.png

    uboot-step 8 内存初始化_第28张图片
    data emrs.png
4.完成了内存的初始化流程之后,就剩下最后的ready了
  • 发送ready到memc_cmd 命令000 使DRAM控制器进入ready状态
  • 检查mem_stat寄存器,检查DRAM控制器是否已经进入ready状态


    uboot-step 8 内存初始化_第29张图片
    memstat.png

代码实现如下:

.text
.global mem_init
mem_init:

ldr r0, =0x7e00f120  @设置xm1data引脚为dramc 数据引脚
mov r1, #0x8
str r1, [r0]

ldr r0, =0x7e001004  @内存控制命令寄存器

mov r1, #0x4         @根据手册得知需要先进入配置模式
str r1, [r0]

ldr r0, =0x7e001010  @刷新寄存器地址
ldr r1, =( ( 7800 / ( 1000000000/133000000 ) + 1 ) )      @设置刷新时间
str r1, [r0]

ldr r0, =0x7e001014  @CAS latency寄存器
mov r1, #(3 << 1)
str r1, [r0]

ldr r0, =0x7e001018  @t_DQSS寄存器
mov r1, #0x1
str r1, [r0]

ldr r0, =0x7e00101c  @T_MRD寄存器
mov r1, #0x2
str r1, [r0]

ldr r0, =0x7e001020   @t_RAS寄存器
ldr r1, =( ( 45 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]

ldr r0, =0x7e001024   @t_RC寄存器
ldr r1, =( ( 68 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]

ldr r0, =0x7e001028   @t_RCD寄存器
ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]

ldr r0, =0x7e00102c   @t_RFC寄存器
ldr r1, =( ( 80 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]

ldr r0, =0x7e001030   @t_RP寄存器
ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]

ldr r0, =0x7e001034   @t_rrd寄存器
ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]

ldr r0, =0x7e001038   @t_wr寄存器
ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
 @  ldr r2, [r0]
str r1, [r0]

ldr r0, =0x7e00103c   @t_wtr寄存器
mov r1, #0x07
str r1, [r0]

ldr r0, =0x7e001040   @t_xp寄存器
mov r1, #0x02
str r1, [r0]

ldr r0, =0x7e001044   @t_xsr寄存器
ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]

ldr r0, =0x7e001048   @t_esr寄存器
ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]

ldr r0, =0x7e00100c   @内存控制配置寄存器
ldr r1, =0x00010012   @配置控制器
str r1, [r0]

ldr r0, =0x7e00104c   @32位DRAM配置控制寄存器
ldr r1, =0x0b45
str r1, [r0]

ldr r0, =0x7e001200   @片选寄存器
ldr r1, =0x150f8
str r1, [r0]

ldr r0, =0x7e001304   @用户配置寄存器
mov r1, #0x0
str r1, [r0]

ldr r0, =0x7e001008
ldr r1, =0x000c0000 @nop
str r1, [r0]

ldr r1, =0x00000000 @Prechargeall
str r1, [r0]

ldr r1, =0x00040000 @Autofresh
str r1, [r0]

ldr r1, =0x000a0000 @emrs 寄存器设置
str r1, [r0]

ldr r1, =0x00080032 @mrs 设置
str r1, [r0]

ldr r0, =0x7e001004  @发送ready命令
mov r1, #0x0
str r1, [r0]

check_dmc1_ready: @检测ready命令是否已经完成

ldr r0, =0x7e001000 
ldr r1, [r0]
mov r2, #0x3
and r1, r1, r2
cmp r1, #0x1
bne check_dmc1_ready
nop
mov pc, lr

此去经年
[email protected]
August 3, 2016

你可能感兴趣的:(uboot-step 8 内存初始化)