mini6410板uboot的Nand_cp.c
#ifdef CONFIG_S3C64XX
#include <asm/io.h>
#include <linux/mtd/nand.h>
#include <regs.h>
/*
* address format
* 17 16 9 8 0
* ——————————————–
* | block(12bit) | page(5bit) | offset(9bit) |
* ——————————————–
*/
static int nandll_read_page (uchar *buf, ulong addr, int large_block)
{
int i;
int page_size = 512;
if (large_block)
page_size = 2048;
NAND_ENABLE_CE(); /*片选使能*/
NFCMD_REG = NAND_CMD_READ0; /*读命令*/
/* Write Address */
NFADDR_REG = 0; /*写列地址1,正常地址的a0-a7,因为一次读取一页,所以列地址值都为0,2^11刚好2K一页*/
if (large_block)
NFADDR_REG = 0; /*写列地址2,正常地址的a8-a11*/
NFADDR_REG = (addr) & 0xff; /*写行地址1,正常地址的a12-a19*/
NFADDR_REG = (addr >> 8) & 0xff; /*写行地址2,正常地址的a20-a27*/
NFCMD_REG = NAND_CMD_READSTART; /*实际读开始*/
NF_TRANSRnB(); /*等待RnB变成1,ready*/
/* for compatibility(2460). u32 cannot be used. by scsuh */
for(i=0; i < page_size; i++) {
*buf++ = NFDATA8_REG; /*读取一页*/
}
NAND_DISABLE_CE(); /*读完,去使能*/
return 0;
}
/*
* Read data from NAND.
*/
static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)
{
uchar *buf = (uchar *)dst_addr;
int i;
uint page_shift = 9; /*一般512字节*
if (large_block)
page_shift = 11; /*大块2KB字节*
/* Read pages */ /*每次读一页*/
for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) {
nandll_read_page(buf, i, large_block);
}
return 0;
}
int copy_uboot_to_ram (void)
{
int large_block = 0;
int i;
vu_char id;
NAND_ENABLE_CE(); @使能NAND Xm0CSn2的片选信号,就是置0x70200004 NFCONT寄存器的Reg_nCE0为0。
NFCMD_REG = NAND_CMD_READID; @发送读取ID命令,时序参考K9F2G08U0A手册。
NFADDR_REG = 0x00; @发送地址为0
/* wait for a while */
for (i=0; i<200; i++); @等待操作完成
id = NFDATA8_REG; @读取ID的第5字节,芯片大小信息,这里不需要,因为是小端方式,所以先读到第5字节,然后4,3,2,1字节。
id = NFDATA8_REG; @读取ID的第4字节,芯片的块大小,页大小等,芯片大小=nBlocks/芯片*nPages/块*Bytes/页
if (id > 0x80)
large_block = 1; @块>=256KB则设置为大块
/* read NAND Block.
* 128KB ->240KB because of U-Boot size increase. by scsuh
* So, read 0x3c000 bytes not 0x20000(128KB).
*/
return nandll_read_blocks(CFG_PHY_UBOOT_BASE, 0x3c000, large_block); /*从NANDFLASH读取240KB数据到0x57e00000*/
}
#endif