Omap 3530 SDRAM 控制器初始化的一些思考

来源:互联网 发布:mac 修图软件推荐 编辑:程序博客网 时间:2024/06/04 20:14

文章中有不足之处,请高手指点。希望有兴趣的读者交流讨论。谢谢

名词解释

SDRC : OMAP 3530内存接口控制器。

1,DDR SDRAM 原理:

   DDR SDRAM 的原理在网上有很多精彩的分析,在这里不再一一复述。但是觉得比较经典的理论莫过于:以下是来自网上一篇精彩的分析http://hi.baidu.com/dark_hc/blog/item/217dd58f335a84e1503d9235.html

这是一颗128Mbit的内存芯片,从图中可以看出来,白色区域内与SDRAM的结构基本相同,但请注意灰色区域,这是与SDRAM的不同之处。首先就是内部的L-Bank规格。SDRAM中L-Bank存储单元的容量与芯片位宽相同,但在DDR SDRAM中并不是这样,存储单元的容量是芯片位宽的一倍,所以在此不能再套用讲解SDRAM时 “芯片位宽=存储单元容量” 的公式了。也因此,真正的行、列地址数量也与同规格SDRAM不一样了。以本芯片为例,在读取时,L-Bank在内部时钟信号的触发下一次传送8bit的数据给读取锁存器,再分成两路4bit数据传给复用器,由后者将它们合并为一路4bit数据流,然后由发送器在DQS的控制下在外部时钟上升与下降沿分两次传输4bit的数据给北桥。这样,如果时钟频率为100MHz,那么在 I/O端口处,由于是上下沿触发,那么就是传输频率就是200MHz。

现在大家基本明白DDR SDRAM的工作原理了吧,这种内部存储单元容量(也可以称为芯片内部总线位宽)=2×芯片位宽(也可称为芯片I/O总线位宽)的设计,就是所谓的两位预取(2-bit Prefetch),有的公司则贴切的称之为2-n Prefetch(n代表芯片位宽)。

 

以上的分析就是说明了为什么会倍频的原因,但是这也引申出来另外的一个问题。在学习了解DDR SDRAM过程中一定要知道SDRAM CONTROLLER的data 和 address的位宽。Data的位宽代表了如何在硬件上连接DDR SDRAM,同时address的位宽也是同样限制了DDR的型号和寻址方式。

 

omap 3530的DDR SDRAM 是MOBILE DDR SDRAM。没有找到具体在天漠开发板上使用芯片的型号。希望知情的读者交流。

这里举一个列子来说明分析的对象。在文章中主要是通过分析软件的流程,如何初始化硬件的。

 

以下型号并不是天漠开发板上找到的对应的型号:

MT29C2G48MAKLCJA

描述:

Combo Mem 128Mx16 Flash + 128Mx16 LPSDRAM 1.8V Tray

具体的存储属性还要看具体的DATASheet来定。一般来说不同的芯片是在基本的存储单位上做倍数的操作。如:

128 M FLASH + 256M LP SDRAM

128 M FLASH + 512M LP SDRAM

256 M FLASH + 256M LP SDRAM

等等

  

2,OMAP 3530 调试过程:

实际情况和User Manual的描述有所差别。打印信息显示的mobile sdram的型号和参数有区别:

OMAP3 DevKit8000 Board + LPDDR/NAND

DRAM:  256 MB

NAND:  256 MiB (NAND的分析在GPMC控制接口中分析)

在u-boot的代码中没有对SDRC进行初始化,故对于omap 3530的SDRC初始化工作全部在x-lood中进行。

void config_3430sdram_ddr(void)

{

        /* reset sdrc controller */

        __raw_writel(SOFTRESET, SDRC_SYSCONFIG);

        wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000);

        __raw_writel(0, SDRC_SYSCONFIG);

 

        /* setup sdrc to ball mux */

        __raw_writel(SDP_SDRC_SHARING, SDRC_SHARING);

 

        /* SDRC put in weak */

        //(*(unsigned int*)0x6D00008C) = 0x00000020;

 

        /* SDRC_MCFG0 register */

    __raw_writel(0x02584099, SDRC_MCFG_0);

 

        /* SDRC_ACTIM_CTRLA0 register */

    __raw_writel(0xaa9db4c6, SDRC_ACTIM_CTRLA_0);

 

        /* SDRC_ACTIM_CTRLB0 register */

    __raw_writel(0x00011517, SDRC_ACTIM_CTRLB_0);

 

        /* SDRC_RFR_CTRL0 register */

    __raw_writel(0x0004DC01, SDRC_RFR_CTRL);

 

        /* Disble Power Down of CKE cuz of 1 CKE on combo part */

    __raw_writel(0x00000081, SDRC_POWER);

 

        /* SDRC_Manual command register */

    __raw_writel(0x00000000, SDRC_MANUAL_0);

        delay(5000);

    __raw_writel(0x00000001, SDRC_MANUAL_0);

    __raw_writel(0x00000002, SDRC_MANUAL_0); 

    __raw_writel(0x00000002, SDRC_MANUAL_0);

 

        /* SDRC MR0 register */

    __raw_writel(0x00000032, SDRC_MR_0); 

 

        /* SDRC DLLA control register */

    __raw_writel(0x0000A, SDRC_DLLA_CTRL);

        delay(0x20000); // some delay

 

#ifdef CONFIG_DDR_256MB_STACKED

        make_cs1_contiguous();

 

        __raw_writel(0x02584099, SDRC_MCFG_0 + SDRC_CS1_OSET);

        __raw_writel(0xaa9db4c6, SDRC_ACTIM_CTRLA_1);

        __raw_writel(0x00011517, SDRC_ACTIM_CTRLB_1);

 

        __raw_writel(0x0004DC01, SDRC_RFR_CTRL + SDRC_CS1_OSET);

        /* init sequence for mDDR/mSDR using manual commands */

        __raw_writel(0x00000000, SDRC_MANUAL_0 + SDRC_CS1_OSET);

        delay(5000);   /* supposed to be 100us per design spec for mddr/msdr */

        __raw_writel(0x00000001, SDRC_MANUAL_0 + SDRC_CS1_OSET);

        __raw_writel(0x00000002, SDRC_MANUAL_0 + SDRC_CS1_OSET);

        __raw_writel(0x00000002, SDRC_MANUAL_0 + SDRC_CS1_OSET);

        __raw_writel(0x00000032, SDRC_MR_0 + SDRC_CS1_OSET);

#endif

}

 

#endif              // CFG_3430SDRAM_DDR

 

以上代码作用在注释中已经写的很清楚了,对照TRM中的寄存器的说明可以一一对应,但是对于某些寄存器的位操作没有做到一一对应的关系。这里还是要提以下sys control module。这个模块(硬件)定义了所有使用的pin的设置,至于在TRM中已经交待了某些寄存器的初始值是更具这个模块的内容拷贝过来的。至于是什么原因要察看某些章节。在这里推荐一片wiki的文章。http://processors.wiki.ti.com/index.php/DM/AM37_SDRC_registers_configure_in_x-loader

这篇文章中介绍了一些的SDRC寄存器的相关操作和作用。但是只是停留于介绍,并没有对寄存器的位操作进行一一对应的介绍。可以作为参考使用。

结合黑体斜线的代码解释一下这段代码的作用。

(1)其实在omap 第二代的评估板中可以参考“开发办家园”的介绍。使用那个ddr和nand的组合是256M和256M的。但是在uboot的代码显示中确实是256M。如上面的串口log所示。这是什么原因造成的,仔细分析一下。

在天漠的开发板中的不难发现确实是显示了256的DDR,那么这个数值由何而来。关键在于CS1的片选信号。之前调试过2440和2410的开发人员一定知道CS的pin是作为片选来使用的。但是在三星的datasheet中知道所谓的bank是根据CSn来作选择的。当然如果一个bank范围是128M,那么当有6个bank时候,外设的寻址范围就是6x128M。可以看出由于bank的作用,寻址范围倍增了。那么这个范围同样适用于omap的芯片。一个CS的寻址单位是128M,那么两个就是256M。这里主要是芯片支持的类型,看看TRM中对于这个空间描述。

CS0的地址时fixed。然后如果要增加SDRAM的地址就要使用CS1片选。对于CS1的初始化就是设定了CS1所使用的device的大小,接下来在针对CS1的控制类寄存器进行设置。这里设置类似于CS0的设置。目的就是使两块对称的DDR有相同的操作属性。

(2)内部总线:(internal)

其实类似于这样总线的存在,每一款芯片以及生产厂商都有自己的ip。在逻辑上完成的功能是类似的,但是信号的命名以及使用的方法都有区别。这里主要是指的是硬件。在omap3530的总线做要是使用了内部的逻辑这里也先看看两张逻辑图。一张是out-direction另外一张是in-direction。

 

64位的内部中线适用于内部逻辑,这个逻辑可以参考一些硬件的设计文档。

/* Slower full frequency range default timings for x32 operation*/
#define SDP_SDRC_SHARING  0x00000100

32位的data lane是根据SDRC_SHARING寄存来设置的,可以看到xlood中设置的是32bit的位宽。

这里还是对于32bit变为64bit的变换感兴趣,到底是怎么实现的。再看一下data lane的说明:

在回忆在开始介绍ddr的内容中发现其实位宽的一半是在DQS的上升或是下降沿传输的。若是使用32bit的那么就是使用2个DQS的时钟分别在上升和下降沿传输。这样看来所谓的32bit的地址是分为4个byte传输的。DDRdevice的型号应为 128M X 16 bits X 2 chips。故产生了256M的效果。

 

现在唯一遗留下来的问题就是在64bits的总线上产生了32bits的信号,如何识别传输。

1,     三星系列的总线叫做Advanced High-performance Bus(AHB)。

2,     Omap系列的总线叫做L3 L4 connection。这是由SonicsMX。

3,     PowerPc系列的总线叫做60Xbus。

第三个bus仔细阅读过PowerPc的user manual。唯一的遗憾是发现这样的内部总线是不需要调试的,没有相关的寄存器对其功能以及逻辑和状态进行设置,所以看不出区别。非常希望哪位高手可以指点一下。看看硬件的逻辑如何实现。

很可惜,在omap 3530的TRM中没有找到这个总线的逻辑以及硬件信号的命名和解释。(这部分内容不会影响软件的使用)

之所以想要学习一下总线的内容也是“好奇心”。原来连接不同硬件的模块的总线也是具有十分复杂的逻辑。这里的逻辑包括:总线仲裁,总线表示,总线忙,等等。这里的解释不是很规范目的在于更具字面的意思理解总线上发生的状态。