U-boot1.1.6移植到TQ2440開發(fā)板(上)
staticvoids3c2440_nand_reset(void);
staticvoids3c2440_wait_idle(void);
staticvoids3c2440_nand_select_chip(void);
staticvoids3c2440_nand_deselect_chip(void);
staticvoids3c2440_write_cmd(intcmd);
staticvoids3c2440_write_addr(unsignedintaddr);
staticvoids3c2440_write_addr_lp(unsignedintaddr);
staticunsignedchars3c2440_read_data(void);
staticvoids3c2440_nand_reset(void)
{
s3c2440_nand_select_chip();
s3c2440_write_cmd(0xff); // 復(fù)位命令
s3c2440_wait_idle();
s3c2440_nand_deselect_chip();
}
staticvoids3c2440_wait_idle(void)
{
inti;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFSTAT;
while(!(*p & BUSY))
for(i=0; i<10; i++);
}
staticvoids3c2440_nand_select_chip(void)
{
inti;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
s3c2440nand->NFCONT&= ~(1<<1);
for(i=0; i<10; i++);
}
staticvoids3c2440_nand_deselect_chip(void)
{
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
s3c2440nand->NFCONT|= (1<<1);
}
staticvoids3c2440_write_cmd(intcmd)
{
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFCMD;
*p = cmd;
}
staticvoids3c2440_write_addr(unsignedintaddr)
{
inti;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
*p = addr & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 9) & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 17) & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 25) & 0xff;
for(i=0; i<10; i++);
}
staticvoids3c2440_write_addr_lp(unsignedintaddr)
{
inti;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
intcol, page;
col = addr & NAND_BLOCK_MASK_LP;
page = addr / NAND_SECTOR_SIZE_LP;
*p = col & 0xff;
for(i=0; i<10; i++);
*p = (col >> 8) & 0x0f;
for(i=0; i<10; i++);
*p = page & 0xff;
for(i=0; i<10; i++);
*p = (page >> 8) & 0xff;
for(i=0; i<10; i++);
if(b128MB == 0)
*p = (page >> 16) & 0x03;
for(i=0; i<10; i++);
}
staticunsignedchars3c2440_read_data(void)
{
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFDATA;
return*p;
}
staticvoidnand_reset(void)
{
s3c2440_nand_reset();
}
staticvoidwait_idle(void)
{
s3c2440_wait_idle();
}
staticvoidnand_select_chip(void)
{
inti;
s3c2440_nand_select_chip();
for(i=0; i<10; i++);
}
staticvoidnand_deselect_chip(void)
{
s3c2440_nand_deselect_chip();
}
staticvoidwrite_cmd(intcmd)
{
s3c2440_write_cmd(cmd);
}
staticvoidwrite_addr(unsignedintaddr)
{
s3c2440_write_addr(addr);
}
staticvoidwrite_addr_lp(unsignedintaddr)
{
s3c2440_write_addr_lp(addr);
}
staticunsignedcharread_data(void)
{
returns3c2440_read_data();
}
voidnand_init_ll(void)
{
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
#defineTACLS 0
#defineTWRPH0 3
#defineTWRPH1 0
//設(shè)置時序
s3c2440nand->NFCONF= (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
// 使能NAND Flash控制器, 初始化ECC, 禁止片選
s3c2440nand->NFCONT= (1<<4)|(1<<1)|(1<<0);
// 復(fù)位NAND Flash
nand_reset();
}
#if1
intNF_ReadID(void)
{
charpMID;
charpDID;
int nBuff;
char n4thcycle;
inti;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
b128MB = 1;
n4thcycle = nBuff = 0;
nand_init_ll();
nand_select_chip();
write_cmd(0x90); // read id command
*p=0x00 & 0xff;
for( i = 0; i < 100; i++ );
pMID = read_data();
pDID = read_data();
nBuff = read_data();
n4thcycle = read_data();
nand_deselect_chip();
if(pDID >= 0xA0)
{
b128MB = 0;
}
return(pDID);
}
#endif
intnand_read_ll(unsignedchar*buf, unsignedlongstart_addr, intsize)
{
inti, j;
chardat;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
if((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))
{
return-1;
}
nand_select_chip();
for(i=start_addr; i < (start_addr + size);)
{
if(1){
write_cmd(0x50);
*p = 5;
for(j=0; j<10; j++);
*p = (i >> 9) & 0xff;
for(j=0; j<10; j++);
*p = (i >> 17) & 0xff;
for(j=0; j<10; j++);
*p = (i >> 25) & 0xff;
for(j=0; j<10; j++);
wait_idle();
dat = read_data();
write_cmd(0);
nand_deselect_chip();
if(dat != 0xff)
{
i += 16384; // 1 Block = 512*32= 16384
printf("Bad block at 0x%lx,will be skipped1n",i);
}
nand_select_chip();
}
write_cmd(0);
write_addr(i);
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++, i++)
{
*buf = read_data();
buf++;
}
}
nand_deselect_chip();
return0;
}
intnand_read_ll_lp(unsignedchar*buf, unsignedlongstart_addr, intsize)
{
inti, j;
chardat;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
if((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP))
{
return-1;
}
nand_select_chip();
for(i=start_addr; i < (start_addr + size);)
{
if(1){
intcol, page;
col = i & NAND_BLOCK_MASK_LP;
page = i / NAND_SECTOR_SIZE_LP;
write_cmd(0x00);
*p = 5;
for(j=0; j<10; j++);
*p = 8;
for(j=0; j<10; j++);
*p = page & 0xff;
for(j=0; j<10; j++);
*p = (page >> 8) & 0xff;
for(j=0; j<10; j++);
if(b128MB == 0)
*p = (page >> 16) & 0x03;
for(j=0; j<10; j++);
write_cmd(0x30);
wait_idle();
dat = read_data();
nand_deselect_chip();
if(dat != 0xff)
{
i += 131072; // 1 Block = 2048*64= 131072
}
nand_select_chip();
}
write_cmd(0);
write_addr_lp(i);
write_cmd(0x30);
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++)
{
*buf = read_data();
buf++;
}
}
nand_deselect_chip();
return0;
}
intbBootFrmNORFlash(void)
{
volatileunsignedint*pdw = (volatileunsignedint*)0;
unsignedintdwVal;
dwVal = *pdw;
*pdw = 0x12345678;
if(*pdw != 0x12345678)
{
return1;
}
else
{
*pdw = dwVal;
return0;
}
}
intCopyCode2Ram(unsignedlongstart_addr, unsignedchar*buf, intsize)
{
unsignedint*pdwDest;
unsignedint*pdwSrc;
inti;
long*GPBCON=0x56000010;
long*GPBDAT=0x56000014;
long*GPBUP =0x56000018;
*GPBCON=0x295551;
*GPBUP=0xff;
*GPBDAT=0x7be;
評論