s3c6410初始化256Mddr补充

来源:互联网 发布:遇见软件怎么样 编辑:程序博客网 时间:2024/05/10 01:39

6410初始化ddr的过程基本都写在了说明手册中,但是各种教程里都或多或少缺失了对一部分细节的解释。韦东山

的教程真的是很不错,可惜有些地方没解释到,在这里做个补充吧。其中ddr的型号为K4X1G163PC。

首先是对ddr初始化代码的注释部分的补充,如下。

#include "common.h"#define P1MEMSTAT0x7e001000#define P1MEMCCMD0x7e001004#define P1DIRECTCMD0x7e001008#define P1MEMCFG0x7e00100c#define P1REFRESH0x7e001010#define P1CASLAT0x7e001014#define P1T_DQSS0x7e001018#define P1T_MRD0x7e00101c#define P1T_RAS0x7e001020#define P1T_RC0x7e001024#define P1T_RCD0x7e001028#define P1T_RFC0x7e00102c#define P1T_RP0x7e001030#define P1T_RRD0x7e001034#define P1T_WR0x7e001038#define P1T_WTR0x7e00103c#define P1T_XP0x7e001040#define P1T_XSR0x7e001044#define P1T_ESR0x7e001048#define P1MEMCFG20X7e00104c#define MEM_SYS_CFG0x7e00f120#define P1_chip_0_cfg0x7e001200#define P1_user_cfg0x7e001304#define HCLK133000000#define nstoclk(ns)(ns/( 1000000000/HCLK)+1)int sdram_init( void ){set_val( MEM_SYS_CFG, 0x0 );//设置复用的数据线为ddr所用(第七位的设置默认为1,为rom所用)//告诉DRAMC开始配置set_val( P1MEMCCMD, 0x4 );// set refresh period 设置刷新时间set_val( P1REFRESH, nstoclk(7800) );//设置时间参数没有注释的参数均可在ddr手册中查到取值范围set_val( P1CASLAT, ( 3 << 1 ) );  set_val( P1T_DQSS, 0x1 );set_val( P1T_MRD, 0x2 );set_val( P1T_RAS, nstoclk(45) );set_val( P1T_RC, nstoclk(68) );u32 trcd = nstoclk( 23 );set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );u32 trfc = nstoclk( 80 );set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );   u32 trp = nstoclk( 23 );set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) ); set_val( P1T_RRD, nstoclk(15) );set_val( P1T_WR, nstoclk(15) );set_val( P1T_WTR, 0x1 );/*对应tCDLR*/set_val( P1T_XP, 0x1 );/*对应tPDEX*/set_val( P1T_XSR, nstoclk(120) );//set_val( P1T_ESR, nstoclk(120) );/*ddr手册里没有,无需配置?*/// set mem cfg set_nbit( P1MEMCFG, 0, 3, 0x2 );/* 10列 */set_nbit( P1MEMCFG, 3, 3, 0x3 );/* 32Mx16为13行,对64Mx16是14行,这里应设置为0x3*/set_zero( P1MEMCFG, 6 );/* A10/AP */set_nbit( P1MEMCFG, 15, 3, 0x2 );/* Burst 4 */set_nbit( P1MEMCFG2, 0, 4, 0x4 );/*个人认为在异步模式下应设置为0x4*/ set_2bit( P1MEMCFG2, 6, 0x1 );/* 32 bit */set_nbit( P1MEMCFG2, 8, 3, 0x3 );/* Mobile DDR SDRAM */set_2bit( P1MEMCFG2, 11, 0x1 );/*read delay 1 cycle for MDDR*/set_one( P1_chip_0_cfg, 16 );/* Bank-Row-Column organization */// memory initset_val( P1DIRECTCMD, 0xc0000 );// NOPset_val( P1DIRECTCMD, 0x00000 );// prechargeset_val( P1DIRECTCMD, 0x40000 );// auto refreshset_val( P1DIRECTCMD, 0x40000 );// auto refreshset_val( P1DIRECTCMD, 0xa0000 );// EMRSset_val( P1DIRECTCMD, 0x80032 );// MRS// set dramc to "go" statusset_val( P1MEMCCMD, 0x000 );// wait readywhile( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));}

其中仍然没有搞清楚的是tESR的设置以及P1MEMCFG2低四位的设置。实际测试的时候不设置tESR且将P1MEMCFG2

低四位设置为0x4、0x5时,ddr均能正常工作,不明白原因所在。


其次是对时钟部分设置的补充,这也是让我的程序一直调不通的原因。ddr运行时是在时钟上升沿和下降沿都进行

数据的传输,所以提供给ddr的时钟频率是ddr controller时钟频率的一半。在K4X1G163PC的芯片手册第一页可看

到在CL为3时,工作频率可设置为166MHz或133MHz。

1


6410的3.3.4.2节,ARM and AXI/AHB/APB bus clock generation这一块又提到

即ddr controller最高工作频率为266MHz,假设将ddr controller的时钟频率设置为266MHz,则ddr的时钟频率为

133MHz。在上面又说到HCLKX2是是ddr controller的时钟。在3.3.1节硬件架构中有这么一副图



从中可以看到ddr是通过AXI总线连接到6410的,再看3.3.4.1


从中可知AXI总线的时钟是HCLK。所以ddr的时钟就是HCLK。因此在初始化时钟的过程中,必须要将DIV_HCLK设置

1,即HCLKx2的频率始终为HCLK的2倍,否则时钟频率对不上,ddr的初始化就无法正常执行,更不用说使用ddr了。

最后附上调整时钟主要涉及到的几个寄存器的参考图吧。



 



1 0
原创粉丝点击