S5PV210芯片双通道内存配置理解

                                    作者:蓝天

       首先,附一张该芯片的物理空间映射图:

从该图我们可以看到,DRAM被映射到两个空间,分别是

0x2000_0000  0x3FFF_FFFF  512MB  DRAM 0 

0x4000_0000  0x7FFF_FFFF  1024MB  DRAM 1 

也就是说DMC0只能配置为0x2000_0000~0x3fff_ffff的空间,DMC1只能配置为0x4000_0000~0x7fff_ffff的空间

下面在内存配置的时刻,我们会用到这个信息。

再看“谷歌男”的SATE210开发板的内存电路原理图

                 

                                                                                           芯片1

                                                                                           芯片2

开发板的接了4片 64M x 16bit的内存,一片接数据线的低16bit,一片接高16bit,组成了512M32bit挂在CS0 ,两片按数据线的高低16bit的模式组成了两组,一组挂在DMC0CS0,另外一组挂在DMC1CS0。 从上面图片一组(两片芯片接DMC0上)的引脚配置来看,它把两片 16 位的内存组合成 32 位来用的。只有DQM[3:0] (用来屏蔽高低字节输出,相当于锁存),DQSp[3:0] ,DQSn[3:0] 这几根口线是独立的,其他口线都是复用的。

参考下图理解几根独立口线定义

内存访问地址范围有点不理解,逆向反推看看,先来看代码,在InitSystem.c文件中的void InitDMC()函数(MMU还没有开启,都是直接的寄存器地址访问,不是虚拟地址),关于内存地址配置的语句

    MEMCONTROL里面有个num_chip,就是使用了几个CS信号,开发板虽然每个控制器上挂了两块内存,但是他们是按高 16bits和低 16bits组成的32bits挂在CS0上。只用了一个CS0,对于210来说就是一片,所以设置为 0x0 = 1 chip(但配置代码却是为2两片?),然后 MEMCONTROLmem_width,设为 0x2 = 32-bit 

DMC0通道代码:

// K4T1G164QQ, 

    SetReg32(rDMC0_MEM_CONFIG0, ((0x20<<24)|(0xF0<<16)|(1<<12)|(3<<8)|(1<<4)|(3)));

SetReg32(rDMC0_MEM_CONFIG1, ((0x30<<24)|(0xF0<<16)|(1<<12)|(3<<8)|(1<<4)|(3))); 

DMC1通道代码:

// K4T1G184QQ, 

SetReg32(rDMC1_MEM_CONFIG0, ((0x40<<24)|(0xF0<<16)|(1<<12)|(3<<8)|(1<<4)|(3)));

SetReg32(rDMC1_MEM_CONFIG1, ((0x50<<24)|(0xF0<<16)|(1<<12)|(3<<8)|(1<<4)|(3)));

从上面语句分析得知(chip_basechip_mask决定了DMC相应的片选对应哪一段地址),

DMC0通道内存访问空间是0x20000000~0x2fffffff0x30000000~0x3fffffff

DMC1通道内存访问空间是0x40000000~0x4fffffff0x50000000~0x5fffffff

配置成了连续的空间,范围从0x20000000~0x5fffffff,大小为1024MB,可实际芯片大小

问题464MX16组成的,总大小为512MB,显然访问空间大于实际物理内存啊?不理解!!!

   实际有一半的定义是没用的!

问题2: 看下面结构图,我的理解

DMC0

DMC1

组合

地址访问空间

范围

64M x16bit

64M x16bit

64M x32bit

64M

0x20000000~0x23FFFFFF

64M x16bit

64M x16bit 

64M x32bit

64M

0x40000000~0x43FFFFFF


 实际g_oalAddressTable映射表访问

通道

内存芯片

地址访问空间

范围

DMC0

64M x16bit

128MB

0x20000000~0x27FFFFFF

DMC0

64M x16bit

128MB

DMC1

64M x16bit

128MB

0x40000000~0x47FFFFFF

DMC1

64M x16bit

128MB

0x48000000~0x4EA00000

 为什么“物理架构”到实际操作是变成“访问架构”操作方式了呢?怎么是变成这种映射了呢?

后来,重新找到一个ARM体系介绍的书,看到如下信息:

      注意是8bit的宽度,原来一直按着桌面系统32bit的来理解了。

数据类型如下:字,半字,字节

根据上面的信息,重新理解修订此表

DMC0

DMC1

组合

地址访问空间

范围

64M x16bit

64M x16bit

64M x32bit

256MB

0x20000000~0x2FFFFFFF

64M x16bit

64M x16bit 

64M x32bit

256MB

0x40000000~0x4FFFFFFF

上述地址是不连续的,是不是把DMC0寄存器rDMC0_MEM_CONFIG0配置改为如下

SetReg32(rDMC0_MEM_CONFIG0, ((0x30<<24)|(0xF0<<16)|(1<<12)|(3<<8)|(1<<4)|(3)));

这样,DMC0通道内存访问空间是0x30000000~0x3fffffff, DMC1的地址就连续起来了。

(测试了下,image_cfg.incimage_cfg.hDMC0的基址由0x20000000改为0x30000000,首次下载程序运行到OEMInit End,失败,再次重启,则成功!又重新下载了一次,没有出现失败现象,不知刚才为何?)

至于内存如何操控的,交给内存控制器吧,我们先理解到这里。

补充下,这样我们只用到片选0就够了,无需使用片选1了吧(实际物理连线是做BANK线了),函数语句

SetReg32(rDMC0_MEM_CONFIG1, ((0x30<<24)|(0xF0<<16)|(1<<12)|(3<<8)|(1<<4)|(3))); 

SetReg32(rDMC1_MEM_CONFIG1, ((0x30<<24)|(0xF0<<16)|(1<<12)|(3<<8)|(1<<4)|(3))); 

这两句是否可以不用初始化呢,实际初始化也没有关系吧。(测试了下,注释掉代码,程序可以运行!)

另外,MEMCONTROL里面有个num_chip,设置为 0x0 = 1 chip,一个芯片足够了吧,这样两个通道就组合成512MB了。

由于能力有限,理解有错误之处,还请网友给指正。最后,感谢网上的各位,参考众多人的资料,名字也没有记下,谢谢!

你可能感兴趣的:(嵌入式系统)