Uboot21之DDR初始化

时间:2018.4.5  作者:Tom   工作:HWE 说明:如需转载,请注明出处。已注明转载

bl mem_ctrl_asm_init

2)函数位置在uboot/cpu/s5pc11x/s5pc110/cpu_init.S文件中。

3)该函数和裸机中初始化DDR代码是一样的。实际上裸机中初始化DDR的代码就是从这里抄的。配置值也可以从这里抄,但是当时我自己根据理解+抄袭整出来的一份。

4)配置值中其他配置值参考裸机中的解释即可明白,有一个和裸机中讲的不一样。DMC0_MEMCONFIG_0,在裸机中配置值为0x20E01323;在uboot中配置为0x30F01313.这个配置不同就导致结果不同。

在 裸机中DMC0的256MB内存地址范围是0x20000000-0x2FFFFFFF;

在uboot中DMC0的256MB内存地址范围为0x30000000-0x3FFFFFFF。

5)之前在裸机中时配置为2开头的地址,当时并没有说可以配置为3开头。从分析九鼎移植的uboot可以看出:DMC0上允许的地址范围是20000000-3FFFFFFF(一共是512MB),而我们实际只接了256MB物理内存,SoC允许我们给这256MB挑选地址范围。

6)总结一下:在uboot中,可用的物理地址范围为:0x30000000-0x4FFFFFFF。一共512MB,其中30000000-3FFFFFFF为DMC0,40000000-4FFFFFFF为DMC1。

7)我们需要的内存配置值在x210_sd.h的438行到468行之间。分析的时候要注意条件编译的条件,配置头文件中考虑了不同时钟配置下的内存配置值,这个的主要目的是让不同时钟需求的客户都能找到合适自己的内存配置值。

8)在uboot中DMC0和DMC1都工作了,所以在裸机中只要把uboot中的配置值和配置代码全部移植过去,应该是能够让DMC0和DMC1都工作的。

#include <config.h>

#include <s5pc110.h>

 

    .globl mem_ctrl_asm_init

mem_ctrl_asm_init:

 

#ifndef CONFIG_EVT1

 

    ldr r0, =ASYNC_MSYS_DMC0_BASE

#define ASYNC_MSYS_DMC0_BASE        0xF1E00000

    ldr r1, =0x0

    str r1, [r0, #0x0]

    /* This register is removed at EVT1 of C110. */

    ldr r1, =0x0

    str r1, [r0, #0xC]

#endif

上述是设置DRAM的同步方式,选择全双工同步模式。

#ifdef CONFIG_MCP_SINGLE

    /* DMC0 Drive Strength (Setting 2X) */    1.设置DMC0 Drive Strength

    ldr    r0, =ELFIN_GPIO_BASE

#define ELFIN_GPIO_BASE            0xE0200000

    ldr    r1, =0x0000AAAA

    str    r1, [r0, #MP1_0DRV_SR_OFFSET]

#define MP1_0DRV_SR_OFFSET         0x3CC

    。。。。。。。。。。。。。。

    ldr    r1, =0x00002AAA

    str    r1, [r0, #MP1_8DRV_SR_OFFSET]

上述是设置DCM0驱动强度,通用的是2倍的驱动强度

    /* DMC1 Drive Strength (Setting 2X) */

    ldr    r0, =ELFIN_GPIO_BASE

    

    ldr    r1, =0x0000AAAA

    str    r1, [r0, #MP2_0DRV_SR_OFFSET]

。。。。。。。。。。。。。。。。。。。

    ldr    r1, =0x00002AAA

    str    r1, [r0, #MP2_8DRV_SR_OFFSET]

上述是设置DCM1驱动强度,通用的是2倍的驱动强度

 

    /* DMC0 initialization at single Type*/2.初始化PHY DLL

控制器和芯片端都有DLL,芯片端DLL做的简单不需要配置。控制端的DLL需要配置。

    ldr    r0, =APB_DMC_0_BASE

#define APB_DMC_0_BASE            0xF0000000

598页

ldr    r1, =0x00101000                @PhyControl0 DLL parameter setting, manual 0x00101000

    str    r1, [r0, #DMC_PHYCONTROL0]        第二步

#define DMC_PHYCONTROL0             0x18

    ldr    r1, =0x00000086                @PhyControl1 DLL parameter setting, LPDDR/LPDDR2 Case

    str    r1, [r0, #DMC_PHYCONTROL1]        第三步

#define DMC_PHYCONTROL1             0x1C

    ldr    r1, =0x00101002                @PhyControl0 DLL on

    str    r1, [r0, #DMC_PHYCONTROL0]         第三步:DLL打开

    ldr    r1, =0x00101003                @PhyControl0 DLL start

    str    r1, [r0, #DMC_PHYCONTROL0]         第四步:DLL开始工作

find_lock_val:    第十二步:等到DLL稳定

    ldr    r1, [r0, #DMC_PHYSTATUS]        @Load Phystatus register value

#define DMC_PHYSTATUS             0x40

    and    r2, r1, #0x7

    cmp    r2, #0x7                @Loop until DLL is locked

    bne    find_lock_val

    等待DLL锁定CLK,直至完全同步

    and    r1, #0x3fc0

    mov    r2, r1, LSL #18

    orr    r2, r2, #0x100000

    orr    r2 ,r2, #0x1000    

        

    orr    r1, r2, #0x3                @Force Value locking

    str    r1, [r0, #DMC_PHYCONTROL0]

将数据锁至DMC_PHYCONTROL0。

 

#if 0    /* Memory margin test 10.01.05 */

    orr    r1, r2, #0x1                @DLL off

    str    r1, [r0, #DMC_PHYCONTROL0]

#endif

    /* setting DDR2 */第五步:初始化DMC0

    ldr    r1, =0x0FFF2010                @ConControl auto refresh off

    str    r1, [r0, #DMC_CONCONTROL]

    ldr    r1, =DMC0_MEMCONTROL            @MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off

#define DMC0_MEMCONTROL        0x00212400

    str    r1, [r0, #DMC_MEMCONTROL]

    ldr    r1, =DMC0_MEMCONFIG_0            @MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed

#define DMC0_MEMCONFIG_0    0x20E01323

16~23位配置决定了我们可用的内存大小,也就是地址范围。与chip_mask取反。

 

 

    str    r1, [r0, #DMC_MEMCONFIG0]

 

    ldr    r1, =DMC0_MEMCONFIG_1            @MemConfig1

    str    r1, [r0, #DMC_MEMCONFIG1]

    ldr    r1, =0xFF000000                @PrechConfig

    str    r1, [r0, #DMC_PRECHCONFIG]

    ldr    r1, =DMC0_TIMINGA_REF            @TimingAref    7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)

#define DMC0_TIMINGA_REF    0x40e

    str    r1, [r0, #DMC_TIMINGAREF]

 

    ldr    r1, =DMC0_TIMING_ROW            @TimingRow    for @200MHz

#define DMC0_TIMING_ROW        0x10233206

    str    r1, [r0, #DMC_TIMINGROW]

 

    ldr    r1, =DMC0_TIMING_DATA            @TimingData    CL=3

#define DMC0_TIMING_DATA    0x12130005

    str    r1, [r0, #DMC_TIMINGDATA]

    

    ldr    r1, =DMC0_TIMING_PWR            @TimingPower

#define    DMC0_TIMING_PWR        0x0E100222

    str    r1, [r0, #DMC_TIMINGPOWER]

下面开始初始化DDR2

    ldr    r1, =0x07000000                @DirectCmd    chip0 Deselect

    str    r1, [r0, #DMC_DIRECTCMD]

    #define DMC_DIRECTCMD             0x10

    ldr    r1, =0x01000000                @DirectCmd    chip0 PALL

    str    r1, [r0, #DMC_DIRECTCMD]

 

    ldr    r1, =0x00020000                @DirectCmd    chip0 EMRS2

    str    r1, [r0, #DMC_DIRECTCMD]

 

    ldr    r1, =0x00030000                @DirectCmd    chip0 EMRS3

    str    r1, [r0, #DMC_DIRECTCMD]

 

    ldr    r1, =0x00010400                @DirectCmd    chip0 EMRS1 (MEM DLL on, DQS# disable)

    str    r1, [r0, #DMC_DIRECTCMD]

 

    ldr    r1, =0x00000542                @DirectCmd    chip0 MRS (MEM DLL reset) CL=4, BL=4

    str    r1, [r0, #DMC_DIRECTCMD]

 

    ldr    r1, =0x01000000                @DirectCmd    chip0 PALL

    str    r1, [r0, #DMC_DIRECTCMD]

 

    ldr    r1, =0x05000000                @DirectCmd    chip0 REFA

    str    r1, [r0, #DMC_DIRECTCMD]

 

    ldr    r1, =0x00000442                @DirectCmd    chip0 MRS (MEM DLL unreset)

    str    r1, [r0, #DMC_DIRECTCMD]

 

    ldr    r1, =0x00010780                @DirectCmd    chip0 EMRS1 (OCD default)

    str    r1, [r0, #DMC_DIRECTCMD]

 

    ldr    r1, =0x00010400                @DirectCmd    chip0 EMRS1 (OCD exit)

    str    r1, [r0, #DMC_DIRECTCMD]

    下面是chip1的配置,一样的:

    ldr    r1, =0x07100000                @DirectCmd    chip1 Deselect

    str    r1, [r0, #DMC_DIRECTCMD]

。。。。。。。。。。。。。。。。。。。。。。。。。。        

    ldr    r1, =0x00110400                @DirectCmd    chip1 EMRS1 (OCD exit)

    str    r1, [r0, #DMC_DIRECTCMD]

        

    ldr    r1, =0x0FF02030                @ConControl    auto refresh on

    str    r1, [r0, #DMC_CONCONTROL]

        

    ldr    r1, =0xFFFF00FF                @PwrdnConfig

    str    r1, [r0, #DMC_PWRDNCONFIG]

        

    ldr    r1, =0x00202400                @MemControl    BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off

    str    r1, [r0, #DMC_MEMCONTROL]

上面的指令均是主控发给device的指令,用于初始化DDR芯片。

    /* DMC1 initialization */

下面过程是同样的。

    ldr    r0, =APB_DMC_1_BASE

。。。。。。。。。。。。。。。

#else    /* CONFIG_MCP_SINGLE */

----------------------------------------------------------------

    mov    pc, lr

DDR的 控制器和外部DDR芯片初始化完毕!

    .ltorg

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值