<br><font size=2 face="sans-serif">Hi,</font>
<br>
<br><font size=2 face="sans-serif">This patch is specifically for u-bootloader
to program binaries generated by mkyaffsimage, for example, as these binaries
includes the 16 bytes oob. All comments are appreciated.</font>
<br>
<br><font size=2 face="sans-serif">Typical usage will be "nand write.noecc
<source address> <Nand offset address> <size>".</font>
<br>
<br><font size=2 face="sans-serif">Terence.</font>
<br>
<br><font size=2 face="sans-serif">diff /data/src/u-boot-1.1.4/common/cmd_nand.c
./common/cmd_nand.c</font>
<br>
<br><font size=2 face="sans-serif">8a9,12</font>
<br><font size=2 face="sans-serif">> *</font>
<br><font size=2 face="sans-serif">> * Added programming in both
block and spare column area</font>
<br><font size=2 face="sans-serif">> * Specifically, it is meant
for programming binary generated by mkyaffsimage</font>
<br><font size=2 face="sans-serif">> * (C) 2006 Applied Biosystems
Instruments <terence.soh@appliedbiosystems.com></font>
<br><font size=2 face="sans-serif">70a75</font>
<br><font size=2 face="sans-serif">> #define NANDRW_NOECC
0x08</font>
<br><font size=2 face="sans-serif">93a99,105</font>
<br><font size=2 face="sans-serif">> static int nand_write_noecc (struct
nand_chip* nand, size_t to, size_t len,</font>
<br><font size=2 face="sans-serif">>
size_t * retlen, const u_char * buf);</font>
<br><font size=2 face="sans-serif">> static int nand_read_noecc(struct
nand_chip *nand, size_t start, size_t len,</font>
<br><font size=2 face="sans-serif">>
size_t * retlen, u_char *buf);</font>
<br><font size=2 face="sans-serif">> int nand_rw_noecc (struct nand_chip*
nand, int cmd,</font>
<br><font size=2 face="sans-serif">>
size_t start, size_t len,</font>
<br><font size=2 face="sans-serif">>
size_t * retlen, u_char * buf);</font>
<br><font size=2 face="sans-serif">98a111</font>
<br><font size=2 face="sans-serif">> static int pages_per_block;</font>
<br><font size=2 face="sans-serif">219a233,235</font>
<br><font size=2 face="sans-serif">>
else if (cmdtail && !strncmp(cmdtail,
".noecc", 2)) {</font>
<br><font size=2 face="sans-serif">>
cmd |=
NANDRW_NOECC; /* read/write to OOB without
ECC */</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">243,244c259,265</font>
<br><font size=2 face="sans-serif"><
ret = nand_rw(nand_dev_desc + curr_device,
cmd, off, size,</font>
<br><font size=2 face="sans-serif"><
(size_t *)&total, (u_char*)addr);</font>
<br><font size=2 face="sans-serif">---</font>
<br><font size=2 face="sans-serif">>
if(cmd & NANDRW_NOECC){</font>
<br><font size=2 face="sans-serif">>
ret =
nand_rw_noecc(nand_dev_desc + curr_device, cmd, off, size,</font>
<br><font size=2 face="sans-serif">>
&total, (u_char*)addr);</font>
<br><font size=2 face="sans-serif">>
} else {</font>
<br><font size=2 face="sans-serif">>
ret =
nand_rw(nand_dev_desc + curr_device, cmd, off, size,</font>
<br><font size=2 face="sans-serif">>
&total, (u_char*)addr);</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">287a309,310</font>
<br><font size=2 face="sans-serif">> "nand
read.noecc addr off size - read data without ECC"</font>
<br><font size=2 face="sans-serif">> "nand
write.noecc addr off size - write data without ECC"</font>
<br><font size=2 face="sans-serif">447a471,528</font>
<br><font size=2 face="sans-serif">> /* Dealing in (nand->oobblock
+ nand->oobsize) i.e. 528, 2112... bytes per page */</font>
<br><font size=2 face="sans-serif">> int nand_rw_noecc (struct nand_chip*
nand, int cmd,</font>
<br><font size=2 face="sans-serif">>
size_t start, size_t len,</font>
<br><font size=2 face="sans-serif">>
size_t * retlen, u_char * buf)</font>
<br><font size=2 face="sans-serif">> {</font>
<br><font size=2 face="sans-serif">> int
ret = 0, n, total = 0;</font>
<br><font size=2 face="sans-serif">> unsigned
long eblk;</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">> while
(len) {</font>
<br><font size=2 face="sans-serif">>
if (start%((nand->oobblock + nand->oobsize)*pages_per_block)
== 0) {</font>
<br><font size=2 face="sans-serif">>
/* have
crossed into new erase block, deal with</font>
<br><font size=2 face="sans-serif">>
*
it if it is sure marked bad.</font>
<br><font size=2 face="sans-serif">>
*/</font>
<br><font size=2 face="sans-serif">>
eblk =
start/((nand->oobblock + nand->oobsize)*pages_per_block);</font>
<br><font size=2 face="sans-serif">>
eblk *=
nand->oobblock;</font>
<br><font size=2 face="sans-serif">>
if (check_block(nand,
eblk)) {</font>
<br><font size=2 face="sans-serif">>
if (cmd == (NANDRW_WRITE | NANDRW_NOECC))
{</font>
<br><font size=2 face="sans-serif">>
start
+= ((nand->oobblock + nand->oobsize)*pages_per_block);</font>
<br><font size=2 face="sans-serif">>
continue;</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
if(cmd & NANDRW_NOECC){</font>
<br><font size=2 face="sans-serif">>
/* Start
on 528/2112 bytes boundary */</font>
<br><font size=2 face="sans-serif">>
if(start%((nand->oobblock
+ nand->oobsize))){</font>
<br><font size=2 face="sans-serif">>
printf("\nError: Reading/Writing must
start from %d byte page boundary, 0x%8X\n",</font>
<br><font size=2 face="sans-serif">>
(nand->oobblock
+ nand->oobsize),start);</font>
<br><font size=2 face="sans-serif">>
return -1;</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
else{</font>
<br><font size=2 face="sans-serif">>
/* reading and writing without ECC */</font>
<br><font size=2 face="sans-serif">>
if (cmd & NANDRW_READ) {</font>
<br><font size=2 face="sans-serif">>
ret =
nand_read_noecc(nand, start,</font>
<br><font size=2 face="sans-serif">>
min(len,
(nand->oobblock + nand->oobsize)*pages_per_block),</font>
<br><font size=2 face="sans-serif">>
&n,
(u_char*)buf);</font>
<br><font size=2 face="sans-serif">>
} else {</font>
<br><font size=2 face="sans-serif">>
ret =
nand_write_noecc(nand, start,</font>
<br><font size=2 face="sans-serif">>
min(len,
(nand->oobblock + nand->oobsize)*pages_per_block),</font>
<br><font size=2 face="sans-serif">>
&n,
(u_char*)buf);</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
if (ret)</font>
<br><font size=2 face="sans-serif">>
break;</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
start += n;</font>
<br><font size=2 face="sans-serif">>
buf += n;</font>
<br><font size=2 face="sans-serif">>
total += n;</font>
<br><font size=2 face="sans-serif">>
len -= n;</font>
<br><font size=2 face="sans-serif">> }</font>
<br><font size=2 face="sans-serif">> if
(retlen)</font>
<br><font size=2 face="sans-serif">>
*retlen = total;</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">> return
ret;</font>
<br><font size=2 face="sans-serif">> }</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">724a806</font>
<br><font size=2 face="sans-serif">>
pages_per_block = nand->erasesize / nand->oobblock;</font>
<br><font size=2 face="sans-serif">878a961,1010</font>
<br><font size=2 face="sans-serif">> /* Read entire page (without ECC)
*/</font>
<br><font size=2 face="sans-serif">> static int nand_read_noecc(struct
nand_chip *nand, size_t start, size_t len,</font>
<br><font size=2 face="sans-serif">>
size_t * retlen, u_char *buf)</font>
<br><font size=2 face="sans-serif">> {</font>
<br><font size=2 face="sans-serif">> int
col, page;</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">> /*
First we calculate the starting page */</font>
<br><font size=2 face="sans-serif">> /*
Address here take spare area into account */</font>
<br><font size=2 face="sans-serif">> page
= start / (nand->oobblock + nand->oobsize);</font>
<br><font size=2 face="sans-serif">> /*
Get raw starting column */</font>
<br><font size=2 face="sans-serif">> col
= start % (nand->oobblock + nand->oobsize);</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">> /*
Initialize return value */</font>
<br><font size=2 face="sans-serif">> *retlen
= 0;</font>
<br><font size=2 face="sans-serif">>
NAND_ENABLE_CE(nand);
/* set pin low */</font>
<br><font size=2 face="sans-serif">> /*
Loop until all data read */</font>
<br><font size=2 face="sans-serif">> while
(*retlen < len) {</font>
<br><font size=2 face="sans-serif">>
/* Send the read command */</font>
<br><font size=2 face="sans-serif">>
NanD_Command(nand, NAND_CMD_READ0);</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
/* Address to NAND flash don't take the spare
area into account */</font>
<br><font size=2 face="sans-serif">>
if (nand->bus16) {</font>
<br><font size=2 face="sans-serif">>
NanD_Address(nand,
ADDR_COLUMN_PAGE,</font>
<br><font size=2 face="sans-serif">>
(page * nand->oobblock)
+ (col >> 1));</font>
<br><font size=2 face="sans-serif">>
} else {</font>
<br><font size=2 face="sans-serif">>
NanD_Address(nand,
ADDR_COLUMN_PAGE,</font>
<br><font size=2 face="sans-serif">>
(page * nand->oobblock)
+ col);</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
/* Read the data directly into the return
buffer */</font>
<br><font size=2 face="sans-serif">>
if ((*retlen + (nand->oobblock + nand->oobsize
- col)) >= len) {</font>
<br><font size=2 face="sans-serif">>
NanD_ReadBuf(nand,
buf + *retlen, len - *retlen);</font>
<br><font size=2 face="sans-serif">>
*retlen
= len;</font>
<br><font size=2 face="sans-serif">>
/* We're
done */</font>
<br><font size=2 face="sans-serif">>
continue;</font>
<br><font size=2 face="sans-serif">>
} else {</font>
<br><font size=2 face="sans-serif">>
NanD_ReadBuf(nand,
buf + *retlen, nand->oobblock + nand->oobsize - col);</font>
<br><font size=2 face="sans-serif">>
*retlen
+= nand->oobblock + nand->oobsize - col;</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
/* For subsequent reads align to page boundary.
*/</font>
<br><font size=2 face="sans-serif">>
col = 0;</font>
<br><font size=2 face="sans-serif">>
/* Increment page address */</font>
<br><font size=2 face="sans-serif">>
page++;</font>
<br><font size=2 face="sans-serif">> }</font>
<br><font size=2 face="sans-serif">> /*
De-select the NAND device */</font>
<br><font size=2 face="sans-serif">> NAND_DISABLE_CE(nand);
/*
set pin high */</font>
<br><font size=2 face="sans-serif">> /*
Always successful. No ECC */</font>
<br><font size=2 face="sans-serif">> return
0;</font>
<br><font size=2 face="sans-serif">> }</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">1247a1380,1457</font>
<br><font size=2 face="sans-serif">> /* Write entire page (including
out of bound area) */</font>
<br><font size=2 face="sans-serif">> static int nand_write_noecc (struct
nand_chip* nand, size_t to, size_t len,</font>
<br><font size=2 face="sans-serif">>
size_t * retlen, const u_char * buf)</font>
<br><font size=2 face="sans-serif">> {</font>
<br><font size=2 face="sans-serif">> int
i, page, col, ret, cnt = 0;</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">> /*
Initialize return length value */</font>
<br><font size=2 face="sans-serif">> *retlen
= 0;</font>
<br><font size=2 face="sans-serif">> ret
= 0;</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">> /*
Get page */</font>
<br><font size=2 face="sans-serif">> page
= ((int) to) / (nand->oobblock + nand->oobsize);</font>
<br><font size=2 face="sans-serif">> /*
Get the starting column. Should be zero */</font>
<br><font size=2 face="sans-serif">> col
= to % (nand->oobblock + nand->oobsize);</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">> /*
Loop until all data is written */</font>
<br><font size=2 face="sans-serif">> while
(*retlen < len) {</font>
<br><font size=2 face="sans-serif">>
/* Write data into buffer */</font>
<br><font size=2 face="sans-serif">>
if ((col + len - *retlen) >= (nand->oobblock
+ nand->oobsize)) {</font>
<br><font size=2 face="sans-serif">>
/* >=
(nand->oobblock + nand->oobsize) bytes to be written */</font>
<br><font size=2 face="sans-serif">>
for (i
= col, cnt = 0; i < (nand->oobblock + nand->oobsize); i++, cnt++)
{</font>
<br><font size=2 face="sans-serif">>
nand->data_buf[i] = buf[(*retlen + cnt)];</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
} else {</font>
<br><font size=2 face="sans-serif">>
/* Less
than (nand->oobblock + nand->oobsize) bytes to be written */</font>
<br><font size=2 face="sans-serif">>
for (i
= col, cnt = 0; cnt < (len - *retlen); i++, cnt++) {</font>
<br><font size=2 face="sans-serif">>
nand->data_buf[i] = buf[(*retlen + cnt)];</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
/* set pin low */</font>
<br><font size=2 face="sans-serif">>
NAND_ENABLE_CE(nand);</font>
<br><font size=2 face="sans-serif">>
NanD_Command (nand, NAND_CMD_SEQIN);</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
if (nand->bus16) {</font>
<br><font size=2 face="sans-serif">>
NanD_Address
(nand, ADDR_COLUMN_PAGE,</font>
<br><font size=2 face="sans-serif">>
(page * nand->oobblock)
+ (col >> 1));</font>
<br><font size=2 face="sans-serif">>
} else {</font>
<br><font size=2 face="sans-serif">>
NanD_Address
(nand, ADDR_COLUMN_PAGE,</font>
<br><font size=2 face="sans-serif">>
(page * nand->oobblock)
+ col);</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
/* Write out complete page of data */</font>
<br><font size=2 face="sans-serif">>
if (nand->bus16) {</font>
<br><font size=2 face="sans-serif">>
for (i
= 0; i < cnt; i += 2) {</font>
<br><font size=2 face="sans-serif">>
WRITE_NAND (nand->data_buf[i] +</font>
<br><font size=2 face="sans-serif">>
(nand->data_buf[i + 1] << 8),</font>
<br><font size=2 face="sans-serif">>
nand->IO_ADDR);</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
} else {</font>
<br><font size=2 face="sans-serif">>
/* Send
command to begin auto page programming */</font>
<br><font size=2 face="sans-serif">>
for (i
= 0; i < cnt ; i++)</font>
<br><font size=2 face="sans-serif">>
WRITE_NAND (nand->data_buf[i], nand->IO_ADDR);</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">>
/* Send command to actually program the data
*/</font>
<br><font size=2 face="sans-serif">>
NanD_Command (nand, NAND_CMD_PAGEPROG);</font>
<br><font size=2 face="sans-serif">>
NanD_Command (nand, NAND_CMD_STATUS);</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
NAND_WAIT_READY(nand);</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
/* See if device thinks it succeeded */</font>
<br><font size=2 face="sans-serif">>
if(READ_NAND (nand->IO_ADDR) & 0x01)
{</font>
<br><font size=2 face="sans-serif">>
printf
("%s: Failed write, page 0x%08x, ", __FUNCTION__,</font>
<br><font size=2 face="sans-serif">>
page);</font>
<br><font size=2 face="sans-serif">>
ret =
-1;</font>
<br><font size=2 face="sans-serif">>
}</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
/* De-select the NAND device */</font>
<br><font size=2 face="sans-serif">>
NAND_DISABLE_CE(nand);
/* set pin high */</font>
<br><font size=2 face="sans-serif">> </font>
<br><font size=2 face="sans-serif">>
/* Next data start at page boundary */</font>
<br><font size=2 face="sans-serif">>
col = 0;</font>
<br><font size=2 face="sans-serif">>
/* Update written bytes count */</font>
<br><font size=2 face="sans-serif">>
*retlen += cnt;</font>
<br><font size=2 face="sans-serif">>
/* Increment page address */</font>
<br><font size=2 face="sans-serif">>
page++;</font>
<br><font size=2 face="sans-serif">> }</font>
<br><font size=2 face="sans-serif">> return
ret;</font>
<br><font size=2 face="sans-serif">> }</font>
<br><font size=2 face="sans-serif">> </font>