Chinaunix首页 | 论坛 | 博客
  • 博客访问: 79715
  • 博文数量: 11
  • 博客积分: 1401
  • 博客等级: 上尉
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-12 16:16
文章分类
文章存档

2011年(1)

2009年(10)

我的朋友

分类: LINUX

2009-05-21 02:29:00


1.2.2  添加Nand Flash 读取函数


 

board/ mini2440加入NAND Flash读取函数(start.S中需要的nand_read_ll函数)文件nand_read.c ,内容如下:

#include

#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000


#if defined(CONFIG_S3C2440)

#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCONT __REGi(NF_BASE + 0x4)
#define NFCMD __REGb(NF_BASE + 0x8)
#define NFADDR __REGb(NF_BASE + 0xC)
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFSTAT __REGb(NF_BASE + 0x20)

//#define GPDAT        __REGi(GPIO_CTL_BASE+oGPIO_F+oGPIO_DAT)

#define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1))
#define NAND_CHIP_DISABLE (NFCONT |= (1<<1))
#define NAND_CLEAR_RB (NFSTAT |= (1<<2))
#define NAND_DETECT_RB { while(! (NFSTAT&(1<<2)));}

#define BUSY 4
inline void wait_idle(void) {
    while(!(NFSTAT & BUSY));
    NFSTAT |= BUSY;
}

#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)

/* low level nand read function */
int
nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
    int i, j;
    
    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
    return -1;    /* invalid alignment */
    }
    
    NAND_CHIP_ENABLE;
        
    for(i=start_addr; i < (start_addr + size);) {
    /* READ0 */
        NAND_CLEAR_RB;    
        NFCMD = 0;    
    
        /* Write Address */
        NFADDR = i & 0xff;
        NFADDR = (i >> 9) & 0xff;
        NFADDR = (i >> 17) & 0xff;
        NFADDR = (i >> 25) & 0xff;
    
        NAND_DETECT_RB;
    
        for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
        *buf = (NFDATA & 0xff);
        buf++;
        }
    }
    NAND_CHIP_DISABLE;    
    return 0;
}
#endif

#if defined(CONFIG_S3C2410)

#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCMD __REGb(NF_BASE + 0x4)
#define NFADDR __REGb(NF_BASE + 0x8)
#define NFDATA __REGb(NF_BASE + 0xc)
#define NFSTAT __REGb(NF_BASE + 0x10)
#define BUSY 1

#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)

inline void wait_idle(void) {
    int i;
    while(!(NFSTAT & BUSY))
    for(i=0; i<10; i++);
}
/* low level nand read function */
int
nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
    int i, j;
    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
    return -1;    /* invalid alignment */
    }
    /* chip Enable */
    NFCONF &= ~0x800;
    for(i=0; i<10; i++);
    for(i=start_addr; i < (start_addr + size);) {
    /* READ0 */
    NFCMD = 0;
    /* Write Address */
    NFADDR = i & 0xff;
    NFADDR = (i >> 9) & 0xff;
    NFADDR = (i >> 17) & 0xff;
    NFADDR = (i >> 25) & 0xff;
    wait_idle();
    for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
    *buf = (NFDATA & 0xff);
    buf++;
    }
    }
    /* chip Disable */
    NFCONF |= 0x800; /* chip disable */
    return 0;
}
#endif

另外还要修改board/ /mini2440/Makefile文件,nand_read.c编译进u-boot

OBJS := mini2440.o nand_read.o flash.o


1.2.3 修改board/mini2440/lowlevel_init.S文件


    (1)修改BWSCONmini2440 BANK0NOR FlashBANK4DM9000BANK6RAM,对于mini2440,只要修改B4_BWSCON即可

 

#define B3_BWSCON              (DW16 + WAIT + UBLB)

//#define B4_BWSCON            (DW16)

#define B4_BWSCON              (DW16 + WAIT + UBLB)

#define B5_BWSCON              (DW16)

……

 

#define B4_Tacs                0x0     /*  0clk */

#define B4_Tcos                0x3     /*  4clk */

#define B4_Tacc                0x7     /* 14clk */

#define B4_Tcoh                0x1     /*  1clk */

#define B4_Tah                 0x3     /*  4clk */

#define B4_Tacp                0x6     /*  6clk */

#define B4_PMC                 0x0     /* normal */

#define B5_Tacs                0x0     /*  0clk */

 

    (2)然后修改 REFRESH 的刷新周期:

#define B7_SCAN                0x1     /* 9bit */

/* REFRESH parameter */

#define REFEN                  0x1     /* Refresh enable */

#define TREFMD                 0x0     /* CBR(CAS before RAS)/Auto refresh */

#define Trc                    0x3     /* 7clk */

#define Tchr                   0x2     /* 3clk */

//#define REFCNT                      1113    /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */

 

# if defined(CONFIG_S3C2440)

#define Trp            0x2    /* 4clk */

#define REFCNT            1012

#else

#define Trp            0x0    /* 2clk */

#define REFCNT        0x4f4 /* period=7.8125us, HCLK=100Mhz, (2048+1-7.8125*100) */

#endif

_TEXT_BASE:

        .word   TEXT_BASE


1.2.4 修改GPIOPLL的配置


 

/board/ mini2440/mini2440.c 中对GPIOPLL的配置进行修改(参阅开发板的硬件说明和芯片手册)

#elif FCLK_SPEED==1            /* Fout = 202.8MHz */

/*#define M_MDIV       0xA1

#define M_PDIV 0x3

#define M_SDIV 0x1*/

 

#if defined(CONFIG_S3C2410)

/* Fout = 202.8MHz */

#define M_MDIV    0xA1

#define M_PDIV    0x3

#define M_SDIV    0x1

#endif

#if defined(CONFIG_S3C2440)

/* Fout = 405MHz */

#define M_MDIV 0x7f       

#define M_PDIV 0x2

#define M_SDIV 0x1

#endif

/*------------------------*/

#endif

……

 

#elif USB_CLOCK==1

/*#define U_M_MDIV     0x48

#define U_M_PDIV       0x3*/

#if defined(CONFIG_S3C2410)

#define U_M_MDIV    0x48

#define U_M_PDIV    0x3

#endif

 

#if defined(CONFIG_S3C2440)

#define U_M_MDIV 0x38

#define U_M_PDIV 0x2

#endif

#define U_M_SDIV    0x2

#endif

 

为连接LED和蜂鸣器的GPIO修改配置寄存器:

        /* set up the I/O ports */

        gpio->GPACON = 0x007FFFFF;

/*gpio->GPBCON = 0x00044555;*/

#if defined(CONFIG_mini2440_LED)

         gpio->GPBCON = 0x00055555;

#else

        gpio->GPBCON = 0x00044555;

#endif

 

        gpio->GPBUP = 0x000007FF;

 

    为引导linux 内核,修改开发板的类型代码:

        gpio->GPHUP = 0x000007FF;

        /* arch number of SMDK2410-Board */

        //gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

 

#if defined(CONFIG_S3C2410)

    /* arch number of SMDK2410-Board */

    gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

#endif

#if defined(CONFIG_S3C2440)

    /* arch number of S3C2440 -Board */

    gd->bd->bi_arch_number = MACH_TYPE_mini2440 ;

#endif

        /* adress of boot parameters */

 

    为使int board_init (void)设置完成后,LED1LED2同时亮起,在int board_init (void)的最后添加:

        icache_enable();

        dcache_enable();

# if defined(CONFIG_mini2440_LED)

    gpio->GPBDAT = 0x180;

 

//int board_init (void)设置完成后,LED1LED2会亮起!

#endif

        return 0;

阅读(3593) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~