Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片

I.MX6U-ALPHA 开发板上带有一个 256MB/512MB 的 DDR3 内存芯片,一般 Cortex-A 芯片自带RAM 很小,比如 I.MX6U 只有 128KB 的 OCRAM。若要运行 Linux 的话完全不够用,所以必须外扩一片 RAM 芯片, I.MX6U 支持 LPDDR2、LPDDR3/DDR3, I.MX6U-ALPHA开发板上使用的是 DDR3,本篇记录学习如何驱动 I.MX6U-ALPHA 开发板上的这片 DDR3。

DDR3 内存简介

1、RAM、ROM简介

RAM:随机存储器,可以随时进行读写操作,速度很快,掉电以后数据会丢失。比如内存条、SRAM、SDRAM、DDR 等都是 RAM。 RAM 一般用来保存程序数据、中间结果,比如我
们在程序中定义了一个变量 a,然后对这个 a 进行读写操作,示例代码如下:

int a;
a = 10;

a 是一个变量,我们需要很方便的对这个变量进行读写操作,方法就是直接“a”进行读写操作,不需要在乎具体的读写过程。我们可以随意对 RAM 中任何地址的数据进行读写操作,非常方便。

ROM: 只读存储器,我们买手机,通常会告诉你这个手机是 4+64 或 6+128 配置,说的就是 RAM 为 4GB 或 6GB, ROM 为 64G 或128GB。但是这个 ROM 是 Flash,比如 EMMC 或 UFS 存储器,很多人将Flash 叫做ROM。但是 EMMC 和 UFS,甚至是 NAND Flash,这些都是可以进行写操作的!只是写起来比较麻烦,要先进行擦除,然后再发送要写的地址或扇区,最后才是要写入的数据,比如:WM25QXX 系列的 SPI Flash 。相比于RAM,向 ROM 或 Flash 写入数据要复杂很多,意味着速度就会变慢(相比 RAM),但是ROM 和 Flash 可以将容量做的很大,而且掉电以后数据不会丢失,适合用来存储资料,比如音乐、图片、视频等信息。

综上所述, RAM 速度快,可以直接和 CPU 进行通信,但掉电以后数据会丢失,容量不容易做大(和同价格的 Flash 相比)。 ROM(目前来说,更适合叫做 Flash)速度虽然慢,但是容量大、适合存储数据。对于正点原子的 I.MX6U-ALPHA 开发板而言, 256MB/512MB 的 DDR3 就是 RAM,而 512MB NANF Flash 或 8GB EMMC 就是 ROM。

2、SRAM 简介

STM32 单片机开发板都使用到了 SRAM,比如 F103、 F407 等,基本都会外扩一个512KB 或1MB 的 SRAM 的,因为 STM32F103/F407 内部 RAM 比较小,在一些比较耗费内存的应用中会出现内存不够的情况,比如 emWin 做 UI 界面。

SRAM 的全称叫做 Static Random-Access Memory,静态随机存储器,这里的“静态”说的就是只要 SRAM 上电,那么 SRAM 里面的数据就会一直保存着,直到 SRAM 掉电。对于RAM 而言需要可以随机的读取任意一个地址空间内的数据,因此采用了地址线和数据线分离的方式,这里就以 STM32F103/F407 开发板常用的 IS62WV51216 这颗 SRAM 芯片为例学习一下SRAM,这是一颗 16 位宽(数据位为 16 位)、1MB 大小的 SRAM。

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第1张图片

①、 地址线

这部分是地址线,A0~A18,19 根地址线,因此可访问的地址大小就是2^19=524288=512KB。 IS62WV51216 是个 1MB 的 SRAM,IS62WV51216 是 16 位宽的,也就是一次访问 2 个字节,因此需要对512KB 进行乘 2 处理,得到 512KB*2=1MB。位宽的话一般有 8 位/16 位/32 位,根据实际需求选择即可,一般都是根据处理器的 SRAM 控制器位宽来选择 SRAM 位宽。

②、数据线

这部分是 SRAM 的数据线,根据 SRAM 位宽的不同,数据线的数量要不同, 8 位宽就有 8根数据线, 16 位宽就有 16 根数据线, 32 位宽就有 32 根数据线。 IS62WV51216 是一个 16 位宽的SRAM,因此就有 16 根数据线,一次访问可以访问 16bit 的数据,也就是 2 个字节。因此就有高字节和低字节数据之分,其中 IO0~IO7 是低字节数据, IO8~IO15 是高字节数据。
③、控制线

SRAM 要工作还需要一堆控制线, CS2 和 CS1 是片选信号,低电平有效,在一个系统中可能会有多片 SRAM(目的是为了扩展 SRAM 大小或位宽),这时就需要 CS 信号来选择当前使用哪片 SRAM。另外,有的 SRAM 内部其实是由两片 SRAM 拼接起来的,因此就会提供两个片选信号。

OE 是输出使能信号,低电平有效,主控从 SRAM 读取数据。
WE 是写使能信号,低电平有效,主控向 SRAM 写数据。
UB 和 LB 信号,IS62WV51216 是个 16 位宽的 SRAM,分为高字节和低字节, UB 和 LB 这两个控制线都是低电平有效。 UB 为低电平的话表示访问高字节, LB 为低电平的话表示访问低字节。

SRAM 最大的缺点就是成本、价格高,IS62WV51216 这个仅有 1MB大小的 SRAM 售价大概为 5,6 块钱。而 32MB 的 SDRAM ,比如 W9825G6KH ,大概 4,5 块钱,可看出 SDRAM 比 SRAM 容量大,但是价格更低。SRAM 突出的特点就是无需刷新,读写速度快(下面介绍的SDRAM需要刷新来保证数据不丢失)!所以 SRAM通常作为 SOC 的内部 RAM 使用或 Cache 使用,比如 STM32 内存的 RAM 或 I.MX6U 内部的OCRAM 都是 SRAM。

3、SDRAM 简介

SDRAM 全称 Synchronous Dynamic Random Access Memory,同步动态随机存储器,“同步”的意思是 SDRAM 工作需要时钟线,“动态”的意思是 SDRAM 中的数据需要不断的刷新来保证数据不会丢失,“随机”的意思就是可以读写任意地址的数据。

与 SRAM 相比, SDRAM 集成度高、功耗低、成本低、适合做大容量存储,但需要定时刷新来保证数据不丢失。因此 SDRAM 适合用来做内存条,而SRAM 适合做高速缓存或 MCU内部的RAM。 SDRAM 目前已发展到了第四代,分别为:SDRAM、DDR SDRAM、DDR2 SDRAM、 DDR3 SDRAM、 DDR4 SDRAM。 STM32F429/F767/H743 等芯片支持 SDRAM,这里介绍华邦W9825G6KH,W9825G6KH 是一款 16 位宽(数据位为 16 位)、 32MB 的 SDRAM、速度一般为 133MHz、 166MHz 或 200MHz。如下W9825G6KH 框图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第2张图片

①、控制线

SDRAM 也需要很多控制线,如下:
CLK:时钟线,SDRAM 是同步动态随机存储器,“同步”的意思就是时钟,因此需要一根额外的时钟线,这是和 SRAM 最大的不同, SRAM 没有时钟线。
CKE: 时钟使能信号线, SRAM 没有 CKE 信号。
CS: 片选信号,这个和 SRAM 一样,都有片选信号。
RAS:行选通信号,低电平有效, SDRAM 和 SRAM 的寻址方式不同, SDRAM 按照行、列来确定某个具体的存储区域。因此就有行地址和列地址之分,行地址和列地址共同复用同一组地址线,要访问某一个地址区域,必须要发送行地址和列地址,指定要访问哪一行?哪一列?
RAS 是行选通信号,表示要发送行地址,行地址和列地址访问方式如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第3张图片

CAS: 列选通信号,和 RAS 类似,低电平有效,选中以后就可以发送列地址了。
WE: 写使能信号,低电平有效。

②、 A10 地址线

A10 是地址线,这里单独将 A10 地址线给提出来,是因为 A10 地址线还有另外一个作用, A10 还控制着 Auto-precharge,也就是预充电。预充电: SDRAM芯片内部会分为多个 BANK,BANK 后文有介绍。 SDRAM 在读写完成以后,若要对同一个 BANK 中的另一行进行寻址操作就必须将原来有效的行关闭,然后发送新的行/列地址,关闭现在工作的行,准备打开新行的操作就叫做预充电。一般 SDSRAM 都支持自动预充电的功能。

③、地址线

对于 W9825G6KH 来说一共有 A0~A12,13 根地址线,但前面说了 SDRAM 寻址是按照行地址和列地址来访问的,因此这 A0~A12 包含了行地址和列地址。不同的 SDRAM 芯片,根据其位宽、容量等的不同,行列地址数是不同的,这个在 SDRAM 自己的数据手册里面会写清楚。比如 W9825G6KH 的 A0~A8 是列地址,共 9 位列地址, A0~A12 是行地址,共 13位,因此可寻址范围为: 2^9*2^13=4194304B=4MB, W9825G6KH 为 16 位宽(2 个字节),因此还需要对 4MB 进行乘 2 处理,得到 4*2=8MB,W9825G6KH 是一个 32MB 的 SDRAM,但算出来只有 8MB,仅仅为实际容量的 1/4。实际上8MB 只是一个 BANK 的容量, W9825G6KH 共有 4 个 BANK。

④、 BANK 选择线

BS0 和 BS1 是 BANK 选择信号线,在一片 SDRAM 中因为技术、成本等原因,无法做一个全容量的 BANK。而且,因为 SDRAM 的工作原理,单一的 BANK 会带来严重的寻址冲突,减低内存访问效率。为此,在一片 SDRAM 中分割出多块 BANK,一般都是 2 的 n 次方,比如 2,4, 8 等。W9825G6KH 框图中的 ⑤ 部分就是 W9825G6KH 的 4 个 BANK 示意图,每个 SDRAM数据手册里会写清楚自己是几 BANK。前面计算出来了一个 BANK 的大小为 8MB,四个 BANK 的总容量就是 8MB*4=32MB。既然有4个BANK,在访问的时候就要告诉SDRAM,要访问哪个BANK,BS0 和 BS1 就是为此而生的, 4 个 BANK 刚好 2 根线,如果是 8 个 BANK 的话就需要三根线,也就是 BS0~BS2。 BS0、 BS1 这两个线也是 SRAM 所没有的。

⑤、 BANK 区域

BANK 的概念前面已经学,这部分就是 W9825G6KH 的 4 个 BANK 区域。这个概念也是 SRAM 所没有的。

⑥、数据线

W9825G6KH 是 16 位宽的 SDRAM,因此有 16 根数据线, DQ0~DQ15,不同的位宽其数据线数量不同,这个和 SRAM 是一样的。

⑦、高低字节选择

W9825G6KH 是一个 16 位的 SDRAM,因此就分为低字节数据和高字节数据, LDQM 和 UDQM 就是低字节和高字节选择信号,这个也和 SRAM 一样。

4、DDR 简介

DDR 内存是 SDRAM 的升级版本, SDRAM 分为 SDR SDRAM、DDR SDRAM、 DDR2 SDRAM、 DDR3 SDRAM、 DDR4 SDRAM。DDR 本质上其实还是SDRAM,只是随着技术的发展, DDR 在不断更新换代。先来看一下 DDR,也就是DDR1,人们对于速度的追求是永无止境的,当发现 SDRAM 的速度不够快的时候人们就在思考如何提高 SDRAM 的速度, DDR SDRAM 由此诞生。

DDR 全称是 Double Data Rate SDRAM,也就是双倍速率 SDRAM,DDR 的速率(数据传输速率)比 SDRAM 高 1 倍!这 1 倍的速度不是简单的将 CLK 提高 1 倍,SDRAM 在一个 CLK 周期传输一次数据, DDR 在一个 CLK 周期传输两次数据,也就是在上升沿和下降沿各传输一次数据,这个概念叫做预取(prefetch),DDR 的预取为 2bit,因此 DDR 的速度直接加倍!比如 SDRAM 速度一般是 133~200MHz,对应的传输速度就是133~200MT/s(在描述 DDR 速度的时候一般都使用 MT/s,也就是每秒多少兆次数据传输。133MT/S 就是每秒 133M 次数据传输, MT/s 描述的是单位时间内传输速率。)同样 133~200MHz的频率, DDR 的传输速度就变为了 266~400MT/S,所以大家常说的 DDR266、 DDR400 就是这么来的。而 DDR2 在 DDR 基础上进一步增加预取(prefetch),增加到了 4bit,相当于比 DDR 多读取一倍的数据,因此 DDR2 的数据传输速率就是 533~800MT/s,这个也就是大家常说的 DDR2 533、DDR2 800。DDR2 还有其他速度,这里只是说最常见的几种。而 DDR3 在 DDR2 的基础上将预取(prefetch)提高到 8bit,因此获得了比 DDR2 高一倍的传输速率,在总线时钟同样为 266~400MHz 时, DDR3 的传输速率就是 1066~1600MT/S。

I.MX6U 的 MMDC 外设用于连接 DDR,支持 LPDDR2、 DDR3、 DDR3L,最高支持 16 位数据
位宽。总线速度为 400MHz(实际是 396MHz),数据传输速率最大为 800MT/S。

LPDDR3、DDR3 和 DDR3L三者的区别,这三个都是 DDR3,区别主要在于工作电压:

  • LPDDR3叫低功耗 DDR3,工作电压为 1.2V。
  • DDR3 叫做标压 DDR3,工作电压为 1.5V,一般台式内存条都是 DDR3。
  • DDR3L 是低压 DDR3,工作电压 1.35V,手机、嵌入式、笔记本等都使用 DDR3L。

I.MX6U-ALPHA 开发板上接了一个 256MB/512MB 的 DDR3L,16 位宽,型号为NT5CC128M16JR/MT5CC256M16EP,nanya 公司出品,分为对应 256MB 和 512MB 容量。EMMC 核心板上用的 512MB 容量的 DDR3L, NAND 核心板上用的 256MB 容量的 DDR3L。

本讲解我们就以 EMMC 核心板上使用的 NT5CC256M16EP-EK 为例讲解一下 DDR3。可到nanya官网去查找一下此型号相关信息,如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第4张图片

由图可看出:NT5CC256M16EP-EK 是一款总容量为4G bit(代表容量密度是4G bit而不是我们常说的4G byte,这里我一开始就迷糊了,这手册写4Gb,谁能意识到它指的是4G比特,换算之后就是512MB),数据16 位宽、 1.35V、传输速率为 1866MT/S 的 DDR3L 芯片。 正点原子的文件包里有 NT5CC256M16ER-EK 的数据手册。6、硬件资料-》 1、芯片资料-》 NT5CC256M16EP-EK.pdf。数据手册没给DDR3L框图,使用用镁光 MT41K256M16 数据手册里面的结构框图,都是一样的, DDR3L 结构框图如图下:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第5张图片

DDR3L 和 SDRAM 对的结构框图很类似,但是还是有点区别。

①、控制线

ODT:片上终端使能,ODT 使能和禁止片内终端电阻。
ZQ:输出驱动校准的外部参考引脚,此引脚应外接一个 240 欧的电阻到 VSSQ 上,一般直接接地。
RESET: 复位引脚,低电平有效。
CKE: 时钟使能引脚。
A12: A12 是地址引脚,但是有也有另外一个功能,因此也叫做 BC 引脚, A12 会在 READ和 WRITE 命令期间被采样,以决定 burst chop 是否会被执行。
CK 和 CK#: 时钟信号, DDR3 的时钟线是差分时钟线,所有的控制和地址信号都会在 CK对的上升沿和 CK#的下降沿交叉处被采集。
CS#:片选信号,低电平有效。
RAS#、 CAS# 和 WE#:行选通信号、列选通信号和写使能信号。

②、地址线

A[14:0]为地址线, A0~A14,一共 15 根地址线,根据 NT5CC256M16ER-EK 的数据手册可知,列地址为 A0~A9,共 10 根,行地址为 A0~A14,共 15 根,因此一个 BANK 的大小就是2^10*2^15*2=32MB*2=64MB,一共有 8 个 BANK,因此 DDR3L 的容量就是 64*8=512MB。

③、BANK 选择线

一片 DDR3 有 8 个 BANK,因此需要 3 个线才能实现 8 个 BANK 的选择, BA0~BA2 就是用于 BANK 选择的。

④、BANK 区域

DDR3 一般都是 8 个 BANK 区域。

⑤、数据线

因为是 16 位宽的,因此有 16 根数据线,分别为 DQ0~DQ15。

⑥、数据选通引脚

DQS 和 DQS#是数据选通引脚,为差分信号,读的时候是输出,写的时候是输入。

LDQS(有的叫做 DQSL)和 LDQS#(有的叫做 DQSL#)对应低字节,也就是 DQ0~7。

UDQS(有的叫做 DQSU)和 UDQS#(有的叫做 DQSU#)对应高字节,也就是 DQ8~15。

⑦、数据输入屏蔽引脚

DM 是写数据输入屏蔽引脚。同样LDM对应低字节,UDM对应高字节。

DDR3 关键时间参数

1、传输速率

比如 1066MT/S、 1600MT/S、 1866MT/S 等,这决定了 DDR3 内存的最高传输速率。

2、 tRCD 参数

tRCD 全称是 RAS-to-CAS Delay,行寻址到列寻址之间的延迟。 DDR 的寻址流程是先指定 BANK 地址,然后指定行地址,最后指定列地址确定最终寻址的单元。 BANK 地址和行地址是同时发出的,这个命令叫做“行激活” (Row Active)。行激活以后就发送列地址和具体的操作命令(读还是写),这两个是同时发出,因此一般也用“读/写命令”表示列寻址。在行有效(行激活)到读写命令发出的这段时间间隔叫做 tRCD,如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第6张图片

一 般 DDR3 数据手册中会给出 tRCD 的时间值 ,比如正点原子所使用的NT5CC256M16EP-EK 这个 DDR3, tRCD 参数如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第7张图片

由上图可看到 tRCD 为 13.91ns,在初始化 DDR3 的时候需要配置。

有时候我们也会看到“13-13-13”之类的参数,这个是用来描述 CL-tRCD-TRP 的,如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第8张图片

由上图可看出,NT5CC256M16ER-EK 这个 DDR3 的 CL-TRCD-TRP 时间参数为“13-13-13”。因此 tRCD=13,这里的 13 不是 ns 数,而是 CLK 时间数,表示 13 个 CLK 周期。

3、CL 参数

当列地址发出以后就会触发数据传输,但数据从存储单元到内存芯片 IO 接口上还需要一段时间,这段时间就是 CL(CAS Latency),也就是列地址选通潜伏期,如下图:
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第9张图片

CL 参数一般在 DDR3 的数据手册中可以找到,比如 NT5CC256M16EP-EK 的 CL 值就是 13个时钟周期,一般 tRCD 和 CL 大小一样。

4、 AL 参数

DDR 的发展中,提出了一个前置 CAS 的概念,目的是为解决 DDR 中的指令冲突,它允许 CAS 信号紧随着 RAS 发送,相当于将 DDR 中的 CAS 前置了。但是读/写操作并没有因此提前,依旧要保证足够的延迟/潜伏期,为此引入了 AL(Additive Latency),单位也是时钟周期数。 AL+CL 组成了 RL(Read Latency),从 DDR2 开始还引入了写潜伏期 WL(Write Latency),WL 表示写命令发出以后到第一笔数据写入的潜伏期。引入 AL 以后的读时序如下图:
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第10张图片

上图就是镁光 DDR3L 的读时序图,图中四部分的内容:

  1.   tRCD,前面已经说过了。
  2.   AL。
  3.   CL。
  4.   RL 为读潜伏期, RL=AL+CL。

5、tRC参数

tRC 是两个 ACTIVE 命令,或者 ACTIVE 命令到 REFRESH 命令之间的周期, DDR3L 数据手册会给出这个值,比如 NT5CC256M16EP-EK 的 tRC 值为 47.91ns。

6、 tRAS 参数

tRAS 是 ACTIVE 命令到 PRECHARGE 命令之间的最小时间, DDR3L 的数据手册同样也会给出此参数, NT5CC256M16EP-EK 的 tRAS 值为 34ns。

I.MX6U MMDC 控制器

1、MMDC 控制器

STM32 的 FMC 或 FSMC 外设用于连接 SRAM 或 SDRAM,对于 I.MX6U 来说也有 DDR 内存控制器,否则的话它怎么连接 DDR 呢? MMDC 就是 I.MX6U的内存控制器。

MMDC 是一个多模的 DDR 控制器,可连接 16 位宽的 DDR3/DDR3L、16 位宽的 LPDDR2, MMDC 是一个可配置、高性能的 DDR 控制器。MMDC 外设包含一个内核(MMDC_CORE)和 PHY(MMDC_PHY),内核和 PHY 的功能如下:

MMDC 内核:内核负责通过 AXI 接口与系统进行通信、 DDR 命令生成、 DDR 命令优化、读/写数据路径。
MMDC PHY: PHY 负责时序调整和校准,使用特殊校准机制保障数据能在 400MHz被准确捕获。MMDC最高支持DDR3频率是400MHz,800MT/s的传输速率。

MMDC 的主要特性如下:

①、支持 DDR3/DDR3Lx16、支持 LPDDR2x16,不支持 LPDDR1MDDR 和 DDR2。
②、支持单片 256Mbit~8Gbit 容量的 DDR,列地址范围: 8-12 位,行地址范围 11-16bit。 2个片选信号。
③、对于 DDR3,最大支持 8bit 的突发访问。
④、对于 LPDDR2 最大支持 4bit 的突发访问。
⑤、 MMDC 最大频率为 400MHz,因此对应的数据速率为 800MT/S。
⑥、支持各种校准程序,可以自动或手动运行。支持 ZQ 校准外部 DDR 设备, ZQ 校准 DDRI/O 引脚、校准 DDR 驱动能力。

2、MMDC 控制器信号引脚

在使用 STM32 时 FMC/FSMC 的 IO 引脚是带有复用功能的,不接 SRAM 或SDRAM 的话 FMC/FSMC 可用作其他外设 IO 的。但对于 DDR 接口就不一样了,因为DDR 对于硬件要求非常严格,因此 DDR 的引脚都是独立的,一般没有复用功能,只为 DDR引脚使用。 I.MX6U 也有专用的 DDR 引脚,如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第11张图片

由于引脚是 DDR 专属的,因此就不需要 DDR 引脚复用配置,只需要设置 DDR 引脚的电气属性即可,注意, DDR 引脚的电气属性寄存器和普通的外设引脚电气属性寄存器不同!

3、MMDC 控制器时钟源

I.MX6U 的 DDR 或者 MDDC 的时钟频率为 400MHz,那么这 400MHz 时钟源怎么来的呢?查阅 I.MX6ULL 参考手册的《 Chapter 18 Clock ControllerModule(CCM)》章节。 MMDC 时钟源如下图:

主要分为 4 部分,依次来看一下每部分所组的工作:

①、 pre_periph2 时钟选择器,也就是 periph2_clkd 的前级选择器,由 CBCMR 寄存器的PRE_PERIPH2_CLK_SEL 位(bit22:21)来控制,共有四种可选方案,如下表:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第12张图片

当 PRE_PERIPH2_CLK_SEL 为 0x1 的时候选中 PLL2_PFD2 为pre_periph2 时钟源。在《第十六章 主频和时钟配置》中,已将 PLL2_PFD2 设置为396MHz(约等于 400MHz),I.MX6U 内部 boot rom 就是设置 PLL2_PFD2 作为 MMDC 的最终时钟源,这就是 I.MX6U 的 DDR 频率为 400MHz 的原因。

②、 periph2_clk 时钟选择器,由 CBCDR 寄存器的 PERIPH2_CLK_SEL 位(bit26)来控制,当为 0 的时候选择 pll2_main_clk 作为 periph2_clk 的时钟源,当为 1 的时候选择 periph2_clk2_clk作为 periph2_clk 的时钟源。这里肯定要将 PERIPH2_CLK_SEL 设置为 0,也就是选择pll2_main_clk 作为 periph2_clk 的时钟源,因此 periph2_clk=PLL2_PFD0=396MHz。

③、最后就是分频器,由 CBCDR 寄存器的 FABRIC_MMDC_PODF 位(bit5:3)设置分频值,可设置 0~7,分别对应 1~8 分频,要配置 MMDC 的时钟源为 396MHz,那么此处就要设置为 1分频,因此 FABRIC_MMDC_PODF=0。

④、最终作为MMDC控制器的时钟。

以上就是 MMDC 的时钟源设置。

ALPHA 开发板 DDR3L 硬件原理图

正点原子 ALPHA 开发板 EMMC 和 NAND 核心板的 DDR3L 原理图一样

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第13张图片

左侧是 DDR3L 原理图,右边的是 I.MX6U 的 MMDC 控制器 IO。

DDR3L 初始化与测试

1、ddr_stress_tester 简介

NXP 提供了一个 DDR 初始化工具,叫做 ddr_stress_tester。此工具特点如下:

①、此工具通过 USB OTG 接口与开发板相连接,通过 USB OTG 口进行 DDR 的初始化与测试。
②、此工具有一个默认的配置文件,为 excel 表,通过此表可以设置板子的 DDR 信息,最后生成一个.inc 结尾的 DDR 初始化脚本文件。这个.inc 文件就包含了 DDR 的初始化信息,一般都是寄存器地址和对应的寄存器值。
③、此工具会加载.inc 表里面的 DDR 初始化信息,然后通过 USB OTG 接口向板子下载DDR 相关的测试代码,包括初始化代码。
④、对此工具进行简单的设置,即可开始 DDR 测试,一般先做校准,因为不同 PCB 结构不同,必须要做一次校准,校准完成后会得到两个寄存器对应的校准值,需要用这个新的校准值来重新初始化 DDR。
⑤、此工具可测试板子的 DDR 超频性能,一般认为 DDR 能够以超过标准工作频率10%~20%稳定工作的话就认定此硬件 DDR 走线正常。
⑥、此工具也可对 DDR 进行 12 小时的压力测试。

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第14张图片

2、DDR3L 驱动配置

1、安装 ddr_stress_tester

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第15张图片

2、配置 DDR3L,生成初始化脚本

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第16张图片

I.MX6UL_DDR3_Script_Aid_V0.02.xlsx就是NXP为I.MX6UL编写的DDR3配置excel表。

打开 I.MX6UL_DDR3_Script_Aid_V0.02.xlsx,打开以后下图(配置excel表):

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第17张图片

最下方有三个选项卡,这三个选项卡的功能如下:
①、 Readme 选项卡,帮助信息,告诉用户此文件如何使用。

②、 Register Configuration,用于完成寄存器配置,也就是配置DDR3,此选项卡是重点。

③、 RealView.inc ,配置好 Register Configuration 选项卡后, RealView.inc选项卡里面就保存着寄存器地址和对应的寄存器值。需要另外新建一个后缀为.inc 的文件来保存 RealView.inc 中的初始化脚本内容, ddr_stress_testr 软件要使用此.inc 结尾的初始化脚本文件来初始化 DDR3。

“Register Configuration”选项卡,如下图配置界面:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第18张图片

具体的配置界面,主要分为三部分:
①、 Device Information:DDR3 芯片设备信息设置,此部分要根据所使用的 DDR3 芯片来设置,具体的设置项如下:
Manufacturer:DDR3 芯片厂商,默认为镁光(Micron),这个没有意义,比如我们用的 nanya的 DDR3,但是此配置文件也是可以使用的。
Memory part number:DDR3 芯片型号,可以不用设置,没有实际意义。
Memory type: DDR3 类型,有 DDR3-800、 DDR3-1066、 DDR3-1333 和 DDR3-1600,在此选项右侧有个下拉箭头,点击下拉箭头即可查看所有的可选选项,从图中可以看出,最大只能选择 DDR3-1600,没有 DDR3-1866 选项,因此我们就只能选择 DDR3-1600。如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第19张图片

DRAM density(Gb):DDR3 容量,根据实际情况选择,同样右边有个下拉箭头,打开下拉箭头即可看到所有可选的容量,从图中可以看出,可选的容量为 1、2、4Gb 和 8Gb,如果使用的 512MB 的 DDR3 就应该选择 4,如果使用的 256MB 的 DDR3 就应该选择 2。如下图:
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第20张图片

DRAM Bus width:DDR3 位宽,正点原子 ALPHA 开发板所有 DDR3 都是 16 位宽,因此选择 16。可选的选项如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第21张图片

Number of Banks:DDR3内部BANK 数量,对于DDR3 来说内部都是 8 BANK,因此固定为 8。
Number of ROW Addresses:行地址宽度,可选 11~16 位,这个要具体所使用的 DDR3 芯片来定,如果是 EMMC 核心板(DDR3 型号为 NT5CC256M16EP-EK),那么行地址为 15 位。如果是 NAND 核心板(DDR3 型号为 NT5CC128M16JR-EK),行地址就为 14 位。
Number COLUMN Addresses: 列地址宽度,可选 9~12 位,EMMC 核心板和 NAND 核心板的 DDR3 列地址都为 10 位。
Page Size(K):DDR3 页大小,可选 1 和 2, NT5CC256M16EP-EK 和 NT5CC128M16JR-EK的页大小都为 2KB,因此选择 2。
Self-Refresh Temperature(SRT):固定为 Extended,不需要修改。
tRCD=tRP=CL(ns):DDR3 的 tRCD-tRP-CL 时间参数,要查阅所使用的 DDR3 芯片手册,NT5CC256M16EP-EK 和 NT5CC128M16JR-EK 都为 13.91ns,因此在后面填写 13.91。
tRC Min(ns):DDR3 的 tRC 时间参数, NT5CC256M16EP-EK 和 NT5CC128M16JR-EK 都为 47.91ns,因此在后面填写 47.91。
tRAS Min(ns):DDR3 的 tRAS 时间参数, NT5CC256M16EP-EK 和 NT5CC128M16JR-EK都为 34ns,因此在后面填写 34。

②、 System Information:此部分设置 I.MX6UL/6ULL 相关属性,具体的设置项如下:

i.Mx Part: 固定为 i.MX6UL。

Bus Width:总线宽度, 16 位宽。

Density per Chip select(Gb): 每个片选对应的 DDR3 容量,可选 1~16,根据实际所使用的DDR3 芯片来填写, 512MB 的话就选择 4, 256MB 的话就选择 2。
Number of Chip Select used: 使用几个片选信号?可选择 1 或 2,正点原子所有核心板都只使用了一个片选信号,因此选择 1。
Total DRAM Density(Gb): 整个 DDR3 的容量,单位为 Gb,如果是 512MB 的话就是 4,如果是 256MB 的话就是 2。
DRAM Clock Freq(MHz): DDR3 工作频率,设置为 400MHz。
DRAM Clock Cycle Time(ns): DDR3 工作频率对应的周期,单位为 ns,如果工作在 400MHz,那么周期就是 2.5ns。
Address Mirror(for CS1): 地址镜像,仅 CS1 有效,此处选择关闭,也就是“Disable”,此选项不需要修改。

③、 SI Configuratin:此部分是信号完整性方面的配置,主要是一些信号线的阻抗设置,这个要咨询硬件工程师,这里直接使用 NXP 的默认设置即可。

DDR3 使用ddr_stress_tester工具进行驱动配置介绍到此结束。

EMMC 核心板 (DDR3 型 号 为NT5CC256M16EP-EK),配置如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第22张图片

配置完成以后点击 RealView.inc 选项卡,如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第23张图片

RealView.inc 就是生成的配置脚本,全部是“寄存器地址=寄存器值”这种形式。 RealView.inc 不能直接用,我们需要新建一个以.inc 结尾的文件,名字自定义,比如我名为“ALIENTEK_512MB”的.inc 文件
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第24张图片

用 notepad++打开新建的 ALIENTEK_512MB.inc 文件,然后将选项卡 RealView.inc 里的所有内容拷贝到 ALIENTEK_512MB.inc 文件中,完成以后如下图:
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第25张图片

至此,使用ddr_stress_tester工具进行 DDR3 配置就全部完成, DDR3 的配置文件 ALIENTEK_512MB.inc 已经得到了,接下来就是使用此配置文件对正点原子 ALPHA 开发板的 DDR3 进行校准并进行超频测试。

3、DDR3L 校准

首先要用 DDR_Tester.exe 软件对正点原子 ALPAH 开发板的 DDR3L 进行校准,因为不同的 PCB 其走线不同,必须要进行校准,经过校准一会 DDR3L 就会工作到最佳状态。

1、将开发板通过 USB OTG 线连接到电脑上

DDR_Tester 软件通过 USB OTG 线将测试程序下载到开发板中,因此首先需要使用 USB OTG 线将开发板和电脑连接起来,Type-C 线连接到电脑。
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第26张图片

USB OTG 线连接成功以后还需要如下两步:
①、弹出 TF 卡,
②、设置拨码开关从 USB 启动
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第27张图片

2、 DDR_Tester 软件
双击“DDR_Tester.exe”,打开测试软件,如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第28张图片

点击 “ Load init Script ” 加载前面已生成的初始化脚本文件ALIENTEK_512MB.inc, 注意,不能有中文路径,否则加载可能会失败!ALIENTEK_512MB.inc 文件加载成功以后还不能直接用,还需要对 DDR Test Tool 软件进行设置,设置完成以后如下图:
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第29张图片

一切设置好以后点击右上方“Download”按钮,将测试代码下载到开发板中(具体下载到不清楚),下载完成以后 DDR Test Tool 下方的信息窗口就会输出一些关于板子的信息,比如 SOC 型号、工作频率、 DDR 配置信息等等。
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第30张图片

DDR Test Tool 工具有三个测试项: DDR Calibration、DDR Stess Test 和 32bit Memory Read/Write,我们首先要做校准测试,因为不同 PCB、不同 DDR3L 芯片对信号的影响不同,必须要进行校准,然后用新的校准值重新初始化 DDR。点击“Calibraton”按钮,如下图:
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第31张图片

点击“Calibration”按钮后就会自动开始校准,最终得到 Write leveling calibtarion、 Read DQS Gating Calibration、 Read calibration 和 Write calibration,共四种校准结果,结果如下:
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第32张图片

校准结果其实就是得到了一些寄存器对应的值,比如 MMDC_MPWLDECTRL0 寄存器地址为 0X021B080C,此寄存器是 PHY 写平衡延时寄存器 0,经过校准后此寄存器的值应该为 0X00000000 , 以此类推。我们需要修改 ALIENTEK_512MB.inc 文 件 , 找到MMDC_MPWLDECTRL0、 MMDC_MPWLDECTRL1、 MPDGCTRL0 PHY0、 MPDGCTRL1 PHY0、MPRDDLCTL PHY0 和 MPWRDLCTL PHY0 这 6 个寄存器,然后将其值改为校准结果的 校准后的值 。在 ALIENTEK_512MB.inc中可能找不到MMDC_MPWLDECTRL1(0x021b0810) 和  MPDGCTRL1 PHY0(0x021b0840)这两个寄存器,找不到就不用修改了。

4、DDR3L 超频测试

校准完成后就可以进行 DDR3 超频测试,超频测试就是为了检验 DDR3 硬件设计合不合理,一般 DDR3 能够超频到比标准频率高 10%~15%的话就认为硬件没有问题,因此对于正点原子的 ALPHA 开发板而言,若 DDR3 能够超频到 440MHz~460MHz 那么就认为DDR3 硬件工作良好。

DDR Test Tool 支持 DDR3 超频测试,只要指定起始频率和终止频率,工具会自动开始一点点的增加频率,直到达到终止频率或测试失败。设置如下图:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第33张图片

超频测试完成以后结果如下图:
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第34张图片

5、DDR3L 驱动总结

ALIENTEK_512MB.inc 就是最终得到的 DDR3L 初始化脚本,其中包括了时钟、 IO 等初始化。 I.MX6U 的 DDR3 接口关于 IO 有一些特殊的寄存器需要初始化,如下表:
Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第35张图片

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第36张图片

接下来看一下 MMDC 外设寄存器初始化及初始化序列,如下表:

Linux-ARM裸机(十二)-DDR3-外接RAM内存芯片_第37张图片

你可能感兴趣的:(linux,arm开发,ubuntu,单片机)