一.u-boot对ddr初始化过程概述
二.u-boot修改
1.修改配置文件
在include/configs/omap4_common.h中修改
/* Defines for SDRAM init */
//#define CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS //wxtongwei 2014.08.12
1) 定义CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS后,u-boot对SDRAM进行默认配置,而默认配置是pandaboard的1GB ddr2
文件arch/arm/cpu/armv7/omap-common/emif-common.c如下函数可以看出
static void do_sdram_init(u32 base)
{
......
#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
emif_get_reg_dump(emif_nr, ®s);
if (!regs) {
debug("EMIF: reg dump not provided\n");
return;
}
#else
......
}
跟踪到emif_get_reg_dump,在文件arch/arm/cpu/armv7/omap4/sdram_elpida.c 中有如下代码
const struct emif_regs emif_regs_elpida_400_mhz_2cs = {
.sdram_config_init = 0x80000eb9,
.sdram_config = 0x80001ab9,
.ref_ctrl = 0x00000618,
.sdram_tim1 = 0x10eb0662,
.sdram_tim2 = 0x20370dd2,
.sdram_tim3 = 0x00b1c33f,
.read_idle_ctrl = 0x000501ff,
.zq_config = 0xd00b3214,
.temp_alert_config = 0xd8016893,
.emif_ddr_phy_ctlr_1_init = 0x049ffff5,
.emif_ddr_phy_ctlr_1 = 0x049ff418
};
static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs)
{
u32 omap4_rev = omap_revision();
/* Same devices and geometry on both EMIFs */
if (omap4_rev == OMAP4430_ES1_0)
*regs = &emif_regs_elpida_380_mhz_1cs;
else if (omap4_rev == OMAP4430_ES2_0)
*regs = &emif_regs_elpida_200_mhz_2cs;
else
*regs = &emif_regs_elpida_400_mhz_2cs;
}
void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
__attribute__((weak, alias("emif_get_reg_dump_sdp")));
这样默认的pandaboard就是使用emif_regs_elpida_400_mhz_2cs配置信息,这样做的好处是可以提高uboot的执行效率
2)要将原来的DDR2 1GB变成原来的2GB所以要将//#define CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS注释掉
同时是在arch/arm/cpu/armv7/omap-common/emif-common.c文件中我们可以看到如下代码
static void do_sdram_init(u32 base)
{
......
#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
......
#else
......
struct lpddr2_device_details cs0_dev_details, cs1_dev_details;
emif_reset_phy(base);
dev_details.cs0_device_details = emif_get_device_details(emif_nr, CS0,
&cs0_dev_details);
dev_details.cs1_device_details = emif_get_device_details(emif_nr, CS1,
&cs1_dev_details);
emif_reset_phy(base);
/* Return if no devices on this EMIF */
if (!dev_details.cs0_device_details &&
!dev_details.cs1_device_details) {
emif_sizes[emif_nr - 1] = 0;
return;
}
if (!in_sdram)
emif_sizes[emif_nr - 1] = get_emif_mem_size(&dev_details);
......
emif_get_device_timings(emif_nr, &dev_details.cs0_device_timings,
&dev_details.cs1_device_timings);
/* Calculate the register values */
emif_calculate_regs(&dev_details, omap_ddr_clk(), &calculated_regs);
regs = &calculated_regs;
#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
......
}
函数 emif_get_device_details主要作用是调用is_lpddr2_present CPU读取DDR的相关配置信,这些信息主要包括manufacturer,type
density,io_width
函数emif_get_device_timings是获取lpddr的时钟频率
函数emif_calculate_regs是根据 emif_get_device_details和emif_get_device_timings获取到的ddr寄存器的值计算出实际的厂商,ddr的容量等
2.修正编译错误
注释#define CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS后编译uboot会出现以下错误:
u-boot-linaro-stable/arch/arm/cpu/armv7/omap-common/emif-common.c:1084: undefined reference to `ddr3_ext_phy_ctrl_const_base'
主要原因是ddr3_init函数中没有定义ddr3_ext_phy_ctrl_const_base
我们也没有用到DDR3,所以干脆直接注释掉相关代码
static void do_sdram_init(u32 base)
{
......
if (!(in_sdram || warm_reset())) {
if (omap_revision() != OMAP5432_ES1_0)
lpddr2_init(base, regs);
//else
//ddr3_init(base, regs); //wxtongwei 2014.08.12
}
......
}
三.uboot参数修改
fatload mmc 0:1 0x80000000 uImage
fatload mmc 0:1 0x81600000 uInitrd
setenv bootargs ro elevator=noop console=ttyO2,115200n8 mem=2G@0x80000000 root=/dev/mmcblk0p2 fixrtc
bootm 0x80000000 0x81600000