DDR


/****************DDR的设置**************/

#include "common.h"

#define MEMCCMD 0x7e001004
#define P1REFRESH 0x7e001010
#define P1CASLAT 0x7e001014
#define MEM_SYS_CFG 0x7e00f120
#define P1MEMCFG 0x7e00100c
#define P1T_DQSS 0x7e001018
#define P1T_MRD  0x7e00101c
#define P1T_RAS  0x7e001020
#define P1T_RC  0x7e001024
#define P1T_RCD  0x7e001028
#define P1T_RFC  0x7e00102c
#define P1T_RP  0x7e001030
#define P1T_RRD  0x7e001034
#define P1T_WR  0x7e001038
#define P1T_WTR  0x7e00103c
#define P1T_XP  0x7e001040
#define P1T_XSR  0x7e001044
#define P1T_ESR  0x7e001048
#define P1MEMCFG2 0X7e00104c
#define P1_chip_0_cfg 0x7e001200

#define P1MEMSTAT 0x7e001000
#define P1MEMCCMD 0x7e001004
#define P1DIRECTCMD 0x7e001008

 
#define HCLK 133000000

#define nstoclk(ns) (ns/( 1000000000/HCLK)+1)

/*******************操作说明********************/

/***************设置动态内存控制器*****************/

int sdram_init( void )                                     //c语言可以写位置无关码,不能使用全局变量和静态变量
{
 // tell dramc to configure    
 set_val( MEMCCMD, 0x4 );      //0x4=100;

//set_val定义

//将vi设置成unsigned int* 指针类型,前面加*表示指针操作

 // set refresh period 
 set_val( P1REFRESH, nstoclk(7800) );   
//  ns->clock

/************刷新周期(DDR芯片手册)************/

//"+1"是四舍五入

 // set timing para  
 set_val( P1CASLAT, ( 3 << 1 ) );  

  //延迟2或者3


 set_val( P1T_DQSS, 0x1 ); // 0.75 - 1.25


 set_val( P1T_MRD, 0x2 );
 set_val( P1T_RAS, nstoclk(45) );

/***************RAS激活时间(DDR芯片手册)*************/


 set_val( P1T_RC, nstoclk(68) );  

 u32 trcd = nstoclk( 23 );


 set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );
 u32 trfc = nstoclk( 80 );
 set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );  
 u32 trp = nstoclk( 23 );
 set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) );
 set_val( P1T_RRD, nstoclk(15) );
 set_val( P1T_WR, nstoclk(15) );
 set_val( P1T_WTR, 0x7 );
 set_val( P1T_XP, 0x2 );
 set_val( P1T_XSR, nstoclk(120) );
 set_val( P1T_ESR, nstoclk(120) );
 
 // set mem cfg
 set_nbit( P1MEMCFG, 0, 3, 0x2 ); 
/* 10 column address *///列地址长度为10位

/* set_nbit: 把从第bit位开始的一共len位消零,然后把这几位设为val */

 /* set_nbit: 把从第bit位开始的一共len位消零,然后把这几位设为val */
 
 set_nbit( P1MEMCFG, 3, 3, 0x2 );  /* 13 row address */

/***********行,列,bank,设置完后***********/


 set_zero( P1MEMCFG, 6 );    /* A10/AP */


 set_nbit( P1MEMCFG, 15, 3, 0x2 ); /* Burst 4 *///突发传输长度
 

/*设置位宽*/
 set_nbit( P1MEMCFG2, 0, 4, 0x5 );
 set_2bit( P1MEMCFG2, 6, 0x1 );                      /* 32 bit */
 set_nbit( P1MEMCFG2, 8, 3, 0x3 );               /* Mobile DDR SDRAM */
 set_2bit( P1MEMCFG2, 11, 0x1 );

 set_one( P1_chip_0_cfg, 16 );                       /* Bank-Row-Column organization */

 

 // memory init

 set_val( P1DIRECTCMD, 0xc0000 ); // NOP
 set_val( P1DIRECTCMD, 0x000 ); // precharge
 set_val( P1DIRECTCMD, 0x40000 );  // auto refresh
 set_val( P1DIRECTCMD, 0x40000 ); // auto refresh
 set_val( P1DIRECTCMD, 0xa0000 ); // EMRS
 set_val( P1DIRECTCMD, 0x80032 );
// MRS

 set_val( MEM_SYS_CFG, 0x0 );
     
 // set dramc to "go" status 
 set_val( P1MEMCCMD, 0x000 );

 // wait ready
 while( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));


}

 

/*****************start.s****************/ 

.globl _start
_start:
/* 硬件相关的设置 */
    /* Peri port setup */

    ldr r0, =0x70000000
    orr r0, r0, #0x13
    mcr p15,0,r0,c15,c2,4       
   
/* 关看门狗 */
/* 往WTCON(0x7E004000)写0 */

 
 ldr r0, =0x7E004000  
 mov r1, #0
 str r1, [r0]

 bl clock_init
 
/* 为调用C函数准备环境 */
 ldr sp, =8*1024
 bl sdram_init                                    //初始化DDR

 

/* 重定位代码 */
/* 把程序的代码段、数据段复制到它的链接地址去 */ 
 adr r0, _start                   /* 获得_start指令当前所在的地址 : 0*/
 ldr r1, =_start                  /* _start的链接地址 0x50000000 */
 
 ldr r2, =bss_start           /* bss段的起始链接地址 */
 
 cmp r0,r1
 beq clean_bss
 
copy_loop:                         //从片内内存复制到DDR里
 ldr r3, [r0], #4
 str r3, [r1], #4
 cmp r1, r2
 bne copy_loop 


/* 把BSS段对应的内存清零 */
clean_bss:
 ldr r0, =bss_start
 ldr r1, =bss_end
 mov r3, #0
 cmp r0, r1
 beq on_ddr
clean_loop:
 str r3, [r0], #4
 cmp r0, r1 
 bne clean_loop 

on_ddr:
/* 调用C函数 */
 ldr pc, =main  /* pc等于main的链接地址 */

//这一步程序才跳到DDR里运行(之前还在片内内存中运行)

 

SECTIONS
{
    . = 0x50000000;               //0x50000000是DRAM的首地址


    .text :
    {
        start.o
        * (.text)
    }
   
    . = ALIGN(4);
    .rodata :
    {
     * (.rodata)
    }
   
    . = ALIGN(4);
 .data :
 {
  * (.data)
 }

    . = ALIGN(4); 
   
    bss_start = . ;  /* 0x50000450 */
   
 .bss :
 {
  * (.bss)     /* i */
  * (.common)
 }
 
 bss_end = . ;   /* 0x50000450 */
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值