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:

[cpp]  view plain copy
  1. /* add by shl */  
  2.   
  3. #ifndef __ASM_ARM_ARCH_DRAM_H_  
  4. #define __ASM_ARM_ARCH_DRAM_H_  
  5.   
  6. #ifndef __ASSEMBLY__  
  7.   
  8. struct s5pv210_dmc0 {  
  9.     unsigned int    concontrol;  
  10.     unsigned int    memcontrol;  
  11.     unsigned int    memconfig0;  
  12.     unsigned int    memconfig1;  
  13.     unsigned int    directcmd;  
  14.     unsigned int    prechconfig;  
  15.     unsigned int    phycontrol0;  
  16.     unsigned int    phycontrol1;  
  17.     unsigned char   res1[0x08];  
  18.     unsigned int    pwrdnconfig;  
  19.     unsigned char   res2[0x04];  
  20.     unsigned int    timingaref;  
  21.     unsigned int    timingrow;  
  22.     unsigned int    timingdata;  
  23.     unsigned int    timingpower;  
  24.     unsigned int    phystatus;  
  25.     unsigned int    chip0status;  
  26.     unsigned int    chip1status;  
  27.     unsigned int    arefstatus;  
  28.     unsigned int    mrstatus;  
  29.     unsigned int    phytest0;  
  30.     unsigned int    phytest1;  
  31. };  
  32.   
  33. struct s5pv210_dmc1 {  
  34.     unsigned int    concontrol;  
  35.     unsigned int    memcontrol;  
  36.     unsigned int    memconfig0;  
  37.     unsigned int    memconfig1;  
  38.     unsigned int    directcmd;  
  39.     unsigned int    prechconfig;  
  40.     unsigned int    phycontrol0;  
  41.     unsigned int    phycontrol1;  
  42.     unsigned char   res1[0x08];  
  43.     unsigned int    pwrdnconfig;  
  44.     unsigned char   res2[0x04];  
  45.     unsigned int    timingaref;  
  46.     unsigned int    timingrow;  
  47.     unsigned int    timingdata;  
  48.     unsigned int    timingpower;  
  49.     unsigned int    phystatus;  
  50.     unsigned int    chip0status;  
  51.     unsigned int    chip1status;  
  52.     unsigned int    arefstatus;  
  53.     unsigned int    mrstatus;  
  54.     unsigned int    phytest0;  
  55.     unsigned int    phytest1;  
  56. };  
  57.   
  58. #endif  
  59.   
  60. #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 了,具体请看源码:

[cpp]  view plain copy
  1. void ddr_init(void)  
  2. {  
  3.     struct s5pv210_dmc0 *const dmc0 = (struct s5pv210_dmc0 *)samsung_get_base_dmc0();  
  4.     struct s5pv210_dmc1 *const dmc1 = (struct s5pv210_dmc1 *)samsung_get_base_dmc1();  
  5.       
  6.     /* DMC0 */  
  7.     writel(0x00101000, &dmc0->phycontrol0);  
  8.     writel(0x00101002, &dmc0->phycontrol0);          /* DLL on */  
  9.     writel(0x00000086, &dmc0->phycontrol1);  
  10.     writel(0x00101003, &dmc0->phycontrol0);          /* DLL start */  
  11.       
  12.     while ((readl(&dmc0->phystatus) & 0x7) != 0x7); /* wait DLL locked */  
  13.   
  14.     writel(0x0FFF2350, &dmc0->concontrol);           /* Auto Refresh Counter should be off */  
  15.     writel(0x00202430, &dmc0->memcontrol);           /* Dynamic power down should be off */  
  16.     writel(0x20E01323, &dmc0->memconfig0);  
  17.       
  18.     writel(0xFF000000, &dmc0->prechconfig);  
  19.     writel(0xFFFF00FF, &dmc0->pwrdnconfig);  
  20.       
  21.     writel(0x00000618, &dmc0->timingaref);           /* 7.8us * 200MHz = 1560 = 0x618  */  
  22.     writel(0x19233309, &dmc0->timingrow);  
  23.     writel(0x23240204, &dmc0->timingdata);  
  24.     writel(0x09C80232, &dmc0->timingpower);  
  25.       
  26.     writel(0x07000000, &dmc0->directcmd);            /* NOP */  
  27.     writel(0x01000000, &dmc0->directcmd);            /* PALL */  
  28.     writel(0x00020000, &dmc0->directcmd);            /* EMRS2 */  
  29.     writel(0x00030000, &dmc0->directcmd);            /* EMRS3 */  
  30.     writel(0x00010400, &dmc0->directcmd);            /* EMRS enable DLL */  
  31.     writel(0x00000542, &dmc0->directcmd);            /* DLL reset */  
  32.     writel(0x01000000, &dmc0->directcmd);            /* PALL */  
  33.     writel(0x05000000, &dmc0->directcmd);            /* auto refresh */  
  34.     writel(0x05000000, &dmc0->directcmd);            /* auto refresh */  
  35.     writel(0x00000442, &dmc0->directcmd);            /* DLL unreset */  
  36.     writel(0x00010780, &dmc0->directcmd);            /* OCD default */  
  37.     writel(0x00010400, &dmc0->directcmd);            /* OCD exit */  
  38.       
  39.     writel(0x0FF02030, &dmc0->concontrol);           /* auto refresh on */  
  40.     writel(0xFFFF00FF, &dmc0->pwrdnconfig);  
  41.     writel(0x00202400, &dmc0->memcontrol);  
  42.   
  43.     /* DMC1 */  
  44.     writel(0x00101000, &dmc1->phycontrol0);  
  45.     writel(0x00101002, &dmc1->phycontrol0);          /* DLL on */  
  46.     writel(0x00000086, &dmc1->phycontrol1);  
  47.     writel(0x00101003, &dmc1->phycontrol0);          /* DLL start */  
  48.   
  49.     while ((readl(&dmc1->phystatus) & 0x7) != 0x7); /* wait DLL locked */  
  50.   
  51.     writel(0x0FFF2350, &dmc1->concontrol);           /* Auto Refresh Counter should be off */  
  52.     writel(0x00202430, &dmc1->memcontrol);           /* Dynamic power down should be off */  
  53.     writel(0x40E01323, &dmc1->memconfig0);  
  54.       
  55.     writel(0xFF000000, &dmc1->prechconfig);  
  56.     writel(0xFFFF00FF, &dmc1->pwrdnconfig);  
  57.       
  58.     writel(0x00000618, &dmc1->timingaref);           /* 7.8us * 200MHz = 1560 = 0x618  */  
  59.     writel(0x19233309, &dmc1->timingrow);  
  60.     writel(0x23240204, &dmc1->timingdata);  
  61.     writel(0x09C80232, &dmc1->timingpower);  
  62.       
  63.     writel(0x07000000, &dmc1->directcmd);            /* NOP */  
  64.     writel(0x01000000, &dmc1->directcmd);            /* PALL */  
  65.     writel(0x00020000, &dmc1->directcmd);            /* EMRS2 */  
  66.     writel(0x00030000, &dmc1->directcmd);            /* EMRS3 */  
  67.     writel(0x00010400, &dmc1->directcmd);            /* EMRS enable DLL */  
  68.     writel(0x00000542, &dmc1->directcmd);            /* DLL reset */  
  69.     writel(0x01000000, &dmc1->directcmd);            /* PALL */  
  70.     writel(0x05000000, &dmc1->directcmd);            /* auto refresh */  
  71.     writel(0x05000000, &dmc1->directcmd);            /* auto refresh */  
  72.     writel(0x00000442, &dmc1->directcmd);            /* DLL unreset */  
  73.     writel(0x00010780, &dmc1->directcmd);            /* OCD default */  
  74.     writel(0x00010400, &dmc1->directcmd);            /* OCD exit */  
  75.       
  76.     writel(0x0FF02030, &dmc1->concontrol);           /* auto refresh on */  
  77.     writel(0xFFFF00FF, &dmc1->pwrdnconfig);  
  78.     writel(0x00202400, &dmc1->memcontrol);  
  79. }  

在 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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值