tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot-spl.bin(内存初始化)

      这节我们完成内存的初始化: 我们在 u-boot-2014.04/board/samsung/tiny210/tiny210.c 中实现它, 由于这个函数只需要在 u-boot-spl.bin 中实现,而 u-boot.bin 不需要,同时 smdkv210.c中的其他函数只需要在 u-boot.bin 中实现,前面分析过,编译 u-boot-spl.bin 时,spl/Makefile 会导出一个宏 CONFIG_SPL_BUILD,我们通过这个宏来控制代码是否被编译,下面列出修改后的框架:

  


   首先在 u-boot-2014.04/arch/arm/include/asm/arch-s5pc1xx/cpu.h 中添加与 S5PV210 相关的寄存器定义,后面会用到 


 编写u-boot-2014.04/arch/arm/include/asm/arch-s5pc1xx/dmc.h:

/* add by shl */

#ifndef __ASM_ARM_ARCH_DRAM_H_
#define __ASM_ARM_ARCH_DRAM_H_

#ifndef __ASSEMBLY__

struct s5pv210_dmc0 {
	unsigned int	concontrol;
	unsigned int	memcontrol;
	unsigned int	memconfig0;
	unsigned int	memconfig1;
	unsigned int	directcmd;
	unsigned int	prechconfig;
	unsigned int	phycontrol0;
	unsigned int	phycontrol1;
	unsigned char	res1[0x08];
	unsigned int	pwrdnconfig;
	unsigned char	res2[0x04];
	unsigned int	timingaref;
	unsigned int	timingrow;
	unsigned int	timingdata;
	unsigned int	timingpower;
	unsigned int	phystatus;
	unsigned int	chip0status;
	unsigned int	chip1status;
	unsigned int	arefstatus;
	unsigned int	mrstatus;
	unsigned int	phytest0;
	unsigned int	phytest1;
};

struct s5pv210_dmc1 {
	unsigned int	concontrol;
	unsigned int	memcontrol;
	unsigned int	memconfig0;
	unsigned int	memconfig1;
	unsigned int	directcmd;
	unsigned int	prechconfig;
	unsigned int	phycontrol0;
	unsigned int	phycontrol1;
	unsigned char	res1[0x08];
	unsigned int	pwrdnconfig;
	unsigned char	res2[0x04];
	unsigned int	timingaref;
	unsigned int	timingrow;
	unsigned int	timingdata;
	unsigned int	timingpower;
	unsigned int	phystatus;
	unsigned int	chip0status;
	unsigned int	chip1status;
	unsigned int	arefstatus;
	unsigned int	mrstatus;
	unsigned int	phytest0;
	unsigned int	phytest1;
};

#endif

#endif

在 u-boot-2014.04/board/samsung/tiny210/tiny210.c 中添加头文件:


同时在 u-boot-2014.04/arch/arm/include/asm/arch-s5pc1xx/cpu.h 中添加宏:


现在就可以在u-boot-2014.04/board/samsung/tiny210/tiny210.c 中 实现 ddr_init 了,具体请看源码:

void ddr_init(void)
{
	struct s5pv210_dmc0 *const dmc0 = (struct s5pv210_dmc0 *)samsung_get_base_dmc0();
	struct s5pv210_dmc1 *const dmc1 = (struct s5pv210_dmc1 *)samsung_get_base_dmc1();
	
	/* DMC0 */
	writel(0x00101000, &dmc0->phycontrol0);
	writel(0x00101002, &dmc0->phycontrol0);			/* DLL on */
	writel(0x00000086, &dmc0->phycontrol1);
	writel(0x00101003, &dmc0->phycontrol0);			/* DLL start */
	
	while ((readl(&dmc0->phystatus) & 0x7) != 0x7); /* wait DLL locked */

	writel(0x0FFF2350, &dmc0->concontrol);			/* Auto Refresh Counter should be off */
	writel(0x00202430, &dmc0->memcontrol);			/* Dynamic power down should be off */
	writel(0x20E01323, &dmc0->memconfig0);
	
	writel(0xFF000000, &dmc0->prechconfig);
	writel(0xFFFF00FF, &dmc0->pwrdnconfig);
	
	writel(0x00000618, &dmc0->timingaref);			/* 7.8us * 200MHz = 1560 = 0x618  */
	writel(0x19233309, &dmc0->timingrow);
	writel(0x23240204, &dmc0->timingdata);
	writel(0x09C80232, &dmc0->timingpower);
	
	writel(0x07000000, &dmc0->directcmd);			/* NOP */
	writel(0x01000000, &dmc0->directcmd);			/* PALL */
	writel(0x00020000, &dmc0->directcmd);			/* EMRS2 */
	writel(0x00030000, &dmc0->directcmd);			/* EMRS3 */
	writel(0x00010400, &dmc0->directcmd);			/* EMRS enable DLL */
	writel(0x00000542, &dmc0->directcmd);			/* DLL reset */
	writel(0x01000000, &dmc0->directcmd); 			/* PALL */
	writel(0x05000000, &dmc0->directcmd);			/* auto refresh */
	writel(0x05000000, &dmc0->directcmd);			/* auto refresh */
	writel(0x00000442, &dmc0->directcmd);			/* DLL unreset */
	writel(0x00010780, &dmc0->directcmd);			/* OCD default */
	writel(0x00010400, &dmc0->directcmd);			/* OCD exit */
	
	writel(0x0FF02030, &dmc0->concontrol);			/* auto refresh on */
	writel(0xFFFF00FF, &dmc0->pwrdnconfig);
	writel(0x00202400, &dmc0->memcontrol);

	/* DMC1 */
	writel(0x00101000, &dmc1->phycontrol0);
	writel(0x00101002, &dmc1->phycontrol0);			/* DLL on */
	writel(0x00000086, &dmc1->phycontrol1);
	writel(0x00101003, &dmc1->phycontrol0);			/* DLL start */

	while ((readl(&dmc1->phystatus) & 0x7) != 0x7); /* wait DLL locked */

	writel(0x0FFF2350, &dmc1->concontrol);			/* Auto Refresh Counter should be off */
	writel(0x00202430, &dmc1->memcontrol);			/* Dynamic power down should be off */
	writel(0x40E01323, &dmc1->memconfig0);
	
	writel(0xFF000000, &dmc1->prechconfig);
	writel(0xFFFF00FF, &dmc1->pwrdnconfig);
	
	writel(0x00000618, &dmc1->timingaref);			/* 7.8us * 200MHz = 1560 = 0x618  */
	writel(0x19233309, &dmc1->timingrow);
	writel(0x23240204, &dmc1->timingdata);
	writel(0x09C80232, &dmc1->timingpower);
	
	writel(0x07000000, &dmc1->directcmd);			/* NOP */
	writel(0x01000000, &dmc1->directcmd);			/* PALL */
	writel(0x00020000, &dmc1->directcmd);			/* EMRS2 */
	writel(0x00030000, &dmc1->directcmd);			/* EMRS3 */
	writel(0x00010400, &dmc1->directcmd);			/* EMRS enable DLL */
	writel(0x00000542, &dmc1->directcmd);			/* DLL reset */
	writel(0x01000000, &dmc1->directcmd); 			/* PALL */
	writel(0x05000000, &dmc1->directcmd);			/* auto refresh */
	writel(0x05000000, &dmc1->directcmd);			/* auto refresh */
	writel(0x00000442, &dmc1->directcmd);			/* DLL unreset */
	writel(0x00010780, &dmc1->directcmd);			/* OCD default */
	writel(0x00010400, &dmc1->directcmd);			/* OCD exit */
	
	writel(0x0FF02030, &dmc1->concontrol);			/* auto refresh on */
	writel(0xFFFF00FF, &dmc1->pwrdnconfig);
	writel(0x00202400, &dmc1->memcontrol);
}

在 ddr_init 函数中使用到了宏  samsung_get_base_dmc0和 samsung_get_base_dmc1:

        struct s5pv210_dmc0 *const dmc0 = (struct s5pv210_dmc0 *)samsung_get_base_dmc0();
struct s5pv210_dmc1 *const dmc1 = (struct s5pv210_dmc1 *)samsung_get_base_dmc1();

这个宏在 u-boot-2014.04/arch/arm/include/asm/arch-s5pc1xx/cpu.h 中定义


以SAMSUNG_BASE(dmc0, DMC0_BASE)这个宏展开即为:

   SAMSUNG_BASE(dmc0, DMC0_BASE)     ----- >>

      static inline unsigned int samsung_get_base_dmc0(void) \
{ \
if (cpu_is_s5pc100()) \
return S5PC100_dmc0; \
else if (cpu_is_s5pc110()) \
return S5PC110_dmc0; \
else \
return 0; \
}

这里首先判断 CPU 类型,这里只判断了 S5PC100A 和 S5PC110,这里判断 CPU 类型同样使用的是宏:


这个宏展开即为:


    这里判断了一个变量 s5p_cpu_id,这个变量通过 s5p_set_cpu_id 函数读取寄存器 PRO_ID 来设置我们不用那么麻烦,直接修改 SAMSUNG_BASE 这个宏,让它直接返回 S5PV210_##base 


    到这里。内存初始化代码已经完成。下一节继续。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值