您的位置:首页 > 产品设计 > 产品经理

【龙芯1c库】换内存芯片后如何修改SDRAM配置(pmon类似)

2018-02-07 18:21 302 查看
由于各种原因难免会涉及更换SDRAM内存芯片,比如为了降低硬件成本,在够用的前提下,一般会选择容量更小的。本文主要讨论在更换了SDRAM芯片后,初始化代码中内存相关参数应该如何修改。这里以ISSI的IS42S16400在“龙芯1c库”中的配置为例(pmon中类似),参考SDRAM芯片手册中,修改SDRAM相关参数。
龙芯1c库是把龙芯1c的常用外设的常用功能封装为一个库,类似于STM32库。完整的源码请移步到https://gitee.com/caogos/OpenLoongsonLib1c

内存容量相关参数

龙芯1c的芯片手册中专门有一章讲解“SDRAM控制器”,除了有一小节讲SDRAM相关寄存器外,还有一小节讲软件中如何配置SDRAM。如下图



内存的参数“我认为”大致可以分为两类,一是和容量大小相关的,二是和时钟时间相关的。其中和时钟时间相关的参数决定了芯片是否符合某某标准,或者兼容某某标准和芯片,在选择SDRAM芯片时,一般会选择兼容的或者一个系列的,这样的话,和时钟时间相关的参数都不要改。需要修改的是容量大小相关的,这里也着重讨论如何修改容量大小相关的参数。
容量大小相关的参数有哪些呢?
前面的龙芯1c芯片手册的截图中已经说了,容量大小相关的参数包含SD_RSIZE(行宽),SD_CSIZE(列宽)和SD_BIT(位宽)。
其中,位宽是指SDRAM芯片的数据线的位数,是8位的,16位的,还是32位的。行宽和列宽复用SDRAM芯片的地址线,行宽和列宽的具体值需要参考SDRAM芯片手册。

从SDRAM芯片手册中提取相关参数

以ISSI的IS42S16400为例,芯片手册中的描述如下



上图中用下划线把重点划出来了,翻译过来就是说一片IS42S16400包含4个bank,每个bank有4096行,256列,数据宽度为16位。
另外,芯片手册中还明确说了行地址线为A0到A11,列地址线的宽度为A0到A7。如下图所示



修改代码

修改源码“sdram_cfg.h”(在pmon中源文件名为sdram_cfg.S)中的宏SD_PARA0中的行宽,列宽和位宽,如下
#define SD_PARA0 (0x7f<<25 | \
(TRAS << 21) | \
(TRFC << 17) | (TRP << 14) | (TCL << 11) | \
(TRCD << 8) | (WIDTH_16 << 6) | (COL_256 << 3) | \
ROW_4K)即
颗粒的行数=ROW_4K
颗粒的列数=COL_256
颗粒的位宽=WIDTH_16
这里把“sdram_cfg.h”的完整源码贴出来

#ifndef __OPENLOONGSON_SDRAM_CFG_H
#define __OPENLOONGSON_SDRAM_CFG_H

//#define SD_FREQ (6 * PLL_M) / (2 * SDRAM_PARAM_DIV_NUM)
#define SD_FREQ (((APB_CLK / 4) * (PLL_MULT / CPU_DIV)) / SDRAM_PARAM_DIV_NUM)

/*
以型号为IS42S16400的SDRAM为例,
物理参数为,
容量:8MB
行宽:12位,即2的12次方,即4K
列宽:8位,即2的8次方,即256
位宽:16位

所以,
颗粒的行数=ROW_4K
颗粒的列数=COL_256
颗粒的位宽=WIDTH_16

再结合宏SD_PARA0和芯片手册中寄存器SD_CONFIG,相信一看就能明白
替换宏SD_PARA0中的行宽、列宽和位宽
*/

/* 颗粒行数 */
#define ROW_1K 0x7
#define ROW_2K 0x0
#define ROW_4K 0x1
#define ROW_8K 0x2
#define ROW_16K 0x3
/* 颗粒列数 */
#define COL_256 0x7
#define COL_512 0x0
#define COL_1K 0x1
#define COL_2K 0x2
#define COL_4K 0x3
/* 颗粒位宽 */
#define WIDTH_8 0x0
#define WIDTH_16 0x1
#define WIDTH_32 0x2

#define TRCD 3
#define TCL 3
#define TRP 3
#define TRFC 8
#define TRAS 6
#define TREF 0x818
#define TWR 2

#define DEF_SEL 0x1
#define DEF_SEL_N 0x0
#define HANG_UP 0x1
#define HANG_UP_N 0x0
#define CFG_VALID 0x1

#define SD_PARA0 (0x7f<<25 | \
(TRAS << 21) | \
(TRFC << 17) | (TRP << 14) | (TCL << 11) | \
(TRCD << 8) | (WIDTH_16 << 6) | (COL_256 << 3) | \
ROW_4K)

#define SD_PARA1 ((HANG_UP_N << 8) | (DEF_SEL_N << 7) | (TWR << 5) | (TREF >> 7))

#define SD_PARA1_EN ((CFG_VALID << 9) | (HANG_UP_N << 8) | \
(DEF_SEL_N << 7) | (TWR << 5) | (TREF >> 7))

#endif
在汇编文件start.S中,将宏SD_PARA0写入寄存器,代码如下 /* 配置内存 */
li msize, MEM_SIZE
#if !defined(NAND_BOOT_EN)

/*
手册建议,先写寄存器SD_CONFIG[31:0],然后再写寄存器的SD_CONFIG[63:32],
即先写低32位,再写高32位。
写三次寄存器,最后一次将最高位置一,即使能
*/

// 写第一次
li t1, 0xbfd00410 // 寄存器SD_CONFIG[31:0]的地址为0xbfd00410
li a1, SD_PARA0 // 宏SD_PARA0在sdram_cfg.S中定义的
sw a1, 0x0(t1) // 将宏SD_PARA0的值写入寄存器SD_CONFIG[31:0]
li a1, SD_PARA1
sw a1, 0x4(t1) // 同理,将宏SD_PARA1的值写入寄存器SD_CONFIG[63:32]

// 写第二次
li a1, SD_PARA0
sw a1, 0x0(t1)
li a1, SD_PARA1
sw a1, 0x4(t1)

// 写第三次
li a1, SD_PARA0
sw a1, 0x0(t1)
li a1, SD_PARA1_EN // 使能
sw a1, 0x4(t1)
// DELAY(100)
#endif
更完整的代码请移步到“龙芯1c库”的git查看。

另外写了一篇关于上电初始化汇编的文章,感兴趣的可以去逛逛。

【龙芯1c库】上电初始化汇编代码注解 http://blog.csdn.net/caogos/article/details/78984158 感谢阅读!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  龙芯 龙芯1c SDRAM 内存